diff --git a/doc/src/Eqs/fix_mvv_dpd.jpg b/doc/src/Eqs/fix_mvv_dpd.jpg
new file mode 100644
index 0000000000..f62ae28bc4
Binary files /dev/null and b/doc/src/Eqs/fix_mvv_dpd.jpg differ
diff --git a/doc/src/Eqs/fix_mvv_dpd.tex b/doc/src/Eqs/fix_mvv_dpd.tex
new file mode 100644
index 0000000000..4652d54b77
--- /dev/null
+++ b/doc/src/Eqs/fix_mvv_dpd.tex
@@ -0,0 +1,21 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ v(t+\frac{\Delta t}{2}) = v(t) + \frac{\Delta t}{2}\cdot a(t),
+$$
+
+$$
+ r(t+\Delta t) = r(t) + \Delta t\cdot v(t+\frac{\Delta t}{2}),
+$$
+
+$$
+ a(t+\Delta t) = \frac{1}{m}\cdot F\left[ r(t+\Delta t), v(t) +\lambda \cdot \Delta t\cdot a(t)\right],
+$$
+
+$$
+ v(t+\Delta t) = v(t+\frac{\Delta t}{2}) + \frac{\Delta t}{2}\cdot a(t++\Delta t),
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_edpd_force.jpg b/doc/src/Eqs/pair_edpd_force.jpg
new file mode 100644
index 0000000000..fabb6f772e
Binary files /dev/null and b/doc/src/Eqs/pair_edpd_force.jpg differ
diff --git a/doc/src/Eqs/pair_edpd_force.tex b/doc/src/Eqs/pair_edpd_force.tex
new file mode 100644
index 0000000000..f6a0ca0d3c
--- /dev/null
+++ b/doc/src/Eqs/pair_edpd_force.tex
@@ -0,0 +1,33 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \mathbf{F}_{ij}^{C} = \alpha_{ij}{\omega_{C}}(r_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{D} = -\gamma {\omega_{D}}(r_{ij})(\mathbf{e}_{ij} \cdot \mathbf{v}_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{R} = \sigma {\omega_{R}}(r_{ij}){\xi_{ij}}\Delta t^{-1/2} \mathbf{e}_{ij},
+$$
+
+$$
+ \omega_{C}(r) = 1 - r/r_c,
+$$
+
+$$
+ \alpha_{ij} = A\cdot k_B(T_i + T_j)/2,
+$$
+
+$$
+ \omega_{D}(r) = \omega^2_{R}(r) = (1-r/r_c)^s,
+$$
+
+$$
+ \sigma_{ij}^2 = 4\gamma k_B T_i T_j/(T_i + T_j),
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_edpd_gov.jpg b/doc/src/Eqs/pair_edpd_gov.jpg
new file mode 100644
index 0000000000..10b303a218
Binary files /dev/null and b/doc/src/Eqs/pair_edpd_gov.jpg differ
diff --git a/doc/src/Eqs/pair_edpd_gov.tex b/doc/src/Eqs/pair_edpd_gov.tex
new file mode 100644
index 0000000000..782cdec99e
--- /dev/null
+++ b/doc/src/Eqs/pair_edpd_gov.tex
@@ -0,0 +1,15 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \frac{\mathrm{d}^2 \mathbf{r}_i}{\mathrm{d} t^2}=
+ \frac{\mathrm{d} \mathbf{v}_i}{\mathrm{d} t}
+ =\mathbf{F}_{i}=\sum_{i\neq j}(\mathbf{F}_{ij}^{C}+\mathbf{F}_{ij}^{D}+\mathbf{F}_{ij}^{R}),
+$$
+
+$$
+ C_v\frac{\mathrm{d} T_i}{\mathrm{d} t}= q_{i} = \sum_{i\neq j}(q_{ij}^{C}+q_{ij}^{V}+q_{ij}^{R}),
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_edpd_heat.jpg b/doc/src/Eqs/pair_edpd_heat.jpg
new file mode 100644
index 0000000000..b9256a1d13
Binary files /dev/null and b/doc/src/Eqs/pair_edpd_heat.jpg differ
diff --git a/doc/src/Eqs/pair_edpd_heat.tex b/doc/src/Eqs/pair_edpd_heat.tex
new file mode 100644
index 0000000000..241a1bad64
--- /dev/null
+++ b/doc/src/Eqs/pair_edpd_heat.tex
@@ -0,0 +1,29 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ q_i^C = \sum_{j \ne i} k_{ij} \omega_{CT}(r_{ij}) \left( \frac{1}{T_i} - \frac{1}{T_j} \right),
+$$
+
+$$
+ q_i^V = \frac{1}{2 C_v}\sum_{j \ne i}{ \left\{ \omega_D(r_{ij})\left[\gamma_{ij} \left( \mathbf{e}_{ij} \cdot \mathbf{v}_{ij} \right)^2 - \frac{\left( \sigma _{ij} \right)^2}{m}\right] - \sigma _{ij} \omega_R(r_{ij})\left( \mathbf{e}_{ij} \cdot \mathbf{v}_{ij} \right){\xi_{ij}} \right\} },
+$$
+
+$$
+ q_i^R = \sum_{j \ne i} \beta _{ij} \omega_{RT}(r_{ij}) d {t^{ - 1/2}} \xi_{ij}^e,
+$$
+
+$$
+ \omega_{CT}(r)=\omega_{RT}^2(r)=\left(1-r/r_{ct}\right)^{s_T},
+$$
+
+$$
+ k_{ij}=C_v^2\kappa(T_i + T_j)^2/4k_B,
+$$
+
+$$
+ \beta_{ij}^2=2k_Bk_{ij},
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_edpd_kappa.jpg b/doc/src/Eqs/pair_edpd_kappa.jpg
new file mode 100644
index 0000000000..158974d374
Binary files /dev/null and b/doc/src/Eqs/pair_edpd_kappa.jpg differ
diff --git a/doc/src/Eqs/pair_edpd_kappa.tex b/doc/src/Eqs/pair_edpd_kappa.tex
new file mode 100644
index 0000000000..ac5ca9f740
--- /dev/null
+++ b/doc/src/Eqs/pair_edpd_kappa.tex
@@ -0,0 +1,9 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \kappa = \frac{315k_B\upsilon }{2\pi \rho C_v r_{ct}^5}\frac{1}{Pr},
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_mdpd_force.jpg b/doc/src/Eqs/pair_mdpd_force.jpg
new file mode 100644
index 0000000000..9b0e573b79
Binary files /dev/null and b/doc/src/Eqs/pair_mdpd_force.jpg differ
diff --git a/doc/src/Eqs/pair_mdpd_force.tex b/doc/src/Eqs/pair_mdpd_force.tex
new file mode 100644
index 0000000000..b5c8d9be4a
--- /dev/null
+++ b/doc/src/Eqs/pair_mdpd_force.tex
@@ -0,0 +1,17 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \mathbf{F}_{ij}^C = Aw_c(r_{ij})\mathbf{e}_{ij} + B(\rho_i+\rho_j)w_d(r_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{D} = -\gamma {\omega_{D}}(r_{ij})(\mathbf{e}_{ij} \cdot \mathbf{v}_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{R} = \sigma {\omega_{R}}(r_{ij}){\xi_{ij}}\Delta t^{-1/2} \mathbf{e}_{ij},
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_tdpd_flux.jpg b/doc/src/Eqs/pair_tdpd_flux.jpg
new file mode 100644
index 0000000000..9da788ae9b
Binary files /dev/null and b/doc/src/Eqs/pair_tdpd_flux.jpg differ
diff --git a/doc/src/Eqs/pair_tdpd_flux.tex b/doc/src/Eqs/pair_tdpd_flux.tex
new file mode 100644
index 0000000000..f753f16acf
--- /dev/null
+++ b/doc/src/Eqs/pair_tdpd_flux.tex
@@ -0,0 +1,21 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ Q_{ij}^D = -\kappa_{ij} w_{DC}(r_{ij}) \left( C_i - C_j \right),
+$$
+
+$$
+ Q_{ij}^R = \epsilon_{ij}\left( C_i + C_j \right) w_{RC}(r_{ij}) \xi_{ij},
+$$
+
+$$
+ w_{DC}(r_{ij})=w^2_{RC}(r_{ij}) = (1 - r/r_{cc})^{\rm power\_{cc}},
+$$
+
+$$
+ \epsilon_{ij}^2 = m_s^2\kappa_{ij}\rho,
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_tdpd_force.jpg b/doc/src/Eqs/pair_tdpd_force.jpg
new file mode 100644
index 0000000000..f6feb35397
Binary files /dev/null and b/doc/src/Eqs/pair_tdpd_force.jpg differ
diff --git a/doc/src/Eqs/pair_tdpd_force.tex b/doc/src/Eqs/pair_tdpd_force.tex
new file mode 100644
index 0000000000..49edff9700
--- /dev/null
+++ b/doc/src/Eqs/pair_tdpd_force.tex
@@ -0,0 +1,29 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \mathbf{F}_{ij}^{C} = A{\omega_{C}}(r_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{D} = -\gamma {\omega_{D}}(r_{ij})(\mathbf{e}_{ij} \cdot \mathbf{v}_{ij})\mathbf{e}_{ij},
+$$
+
+$$
+ \mathbf{F}_{ij}^{R} = \sigma {\omega_{R}}(r_{ij}){\xi_{ij}}\Delta t^{-1/2} \mathbf{e}_{ij},
+$$
+
+$$
+ \omega_{C}(r) = 1 - r/r_c,
+$$
+
+$$
+ \omega_{D}(r) = \omega^2_{R}(r) = (1-r/r_c)^{\rm power\_f},
+$$
+
+$$
+ \sigma^2 = 2\gamma k_B T,
+$$
+
+\end{document}
diff --git a/doc/src/Eqs/pair_tdpd_gov.jpg b/doc/src/Eqs/pair_tdpd_gov.jpg
new file mode 100644
index 0000000000..0ed793a132
Binary files /dev/null and b/doc/src/Eqs/pair_tdpd_gov.jpg differ
diff --git a/doc/src/Eqs/pair_tdpd_gov.tex b/doc/src/Eqs/pair_tdpd_gov.tex
new file mode 100644
index 0000000000..e4b5f5790a
--- /dev/null
+++ b/doc/src/Eqs/pair_tdpd_gov.tex
@@ -0,0 +1,13 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ \frac{\mathrm{d}^2 \mathbf{r}_i}{\mathrm{d} t^2} = \frac{\mathrm{d} \mathbf{v}_i}{\mathrm{d} t}=\mathbf{F}_{i}=\sum_{i\neq j}(\mathbf{F}_{ij}^{C}+\mathbf{F}_{ij}^{D}+\mathbf{F}_{ij}^{R}),
+$$
+
+$$
+ \frac{\mathrm{d} C_{i}}{\mathrm{d} t}= Q_{i} = \sum_{i\neq j}(Q_{ij}^{D}+Q_{ij}^{R}) + Q_{i}^{S},
+$$
+
+\end{document}
diff --git a/doc/src/JPG/examples_edpd.jpg b/doc/src/JPG/examples_edpd.jpg
new file mode 100644
index 0000000000..4d0cde6370
Binary files /dev/null and b/doc/src/JPG/examples_edpd.jpg differ
diff --git a/doc/src/JPG/examples_mdpd.gif b/doc/src/JPG/examples_mdpd.gif
new file mode 100644
index 0000000000..29ace1a0b2
Binary files /dev/null and b/doc/src/JPG/examples_mdpd.gif differ
diff --git a/doc/src/JPG/examples_mdpd_first.jpg b/doc/src/JPG/examples_mdpd_first.jpg
new file mode 100644
index 0000000000..958912e662
Binary files /dev/null and b/doc/src/JPG/examples_mdpd_first.jpg differ
diff --git a/doc/src/JPG/examples_mdpd_last.jpg b/doc/src/JPG/examples_mdpd_last.jpg
new file mode 100644
index 0000000000..1bf8b9ac82
Binary files /dev/null and b/doc/src/JPG/examples_mdpd_last.jpg differ
diff --git a/doc/src/JPG/examples_tdpd.jpg b/doc/src/JPG/examples_tdpd.jpg
new file mode 100644
index 0000000000..c00e83e003
Binary files /dev/null and b/doc/src/JPG/examples_tdpd.jpg differ
diff --git a/doc/src/Section_commands.txt b/doc/src/Section_commands.txt
index 571c6c4920..fda727ec05 100644
--- a/doc/src/Section_commands.txt
+++ b/doc/src/Section_commands.txt
@@ -685,6 +685,7 @@ package"_Section_start.html#start_3.
"drude"_fix_drude.html,
"drude/transform/direct"_fix_drude_transform.html,
"drude/transform/reverse"_fix_drude_transform.html,
+"edpd/source"_fix_dpd_source.html,
"eos/cv"_fix_eos_cv.html,
"eos/table"_fix_eos_table.html,
"eos/table/rx"_fix_eos_table_rx.html,
@@ -704,6 +705,9 @@ package"_Section_start.html#start_3.
"meso"_fix_meso.html,
"manifoldforce"_fix_manifoldforce.html,
"meso/stationary"_fix_meso_stationary.html,
+"mvv/dpd"_fix_mvv_dpd.html,
+"mvv/edpd"_fix_mvv_dpd.html,
+"mvv/tdpd"_fix_mvv_dpd.html,
"nve/dot"_fix_nve_dot.html,
"nve/dotc/langevin"_fix_nve_dotc_langevin.html,
"nve/manifold/rattle"_fix_nve_manifold_rattle.html,
@@ -732,6 +736,7 @@ package"_Section_start.html#start_3.
"smd/move/triangulated/surface"_fix_smd_move_triangulated_surface.html,
"smd/setvel"_fix_smd_setvel.html,
"smd/wall/surface"_fix_smd_wall_surface.html,
+"tdpd/source"_fix_dpd_source.html,
"temp/rescale/eff"_fix_temp_rescale_eff.html,
"ti/spring"_fix_ti_spring.html,
"ttm/mod"_fix_ttm.html,
@@ -836,6 +841,7 @@ package"_Section_start.html#start_3.
"cnp/atom"_compute_cnp_atom.html,
"dpd"_compute_dpd.html,
"dpd/atom"_compute_dpd_atom.html,
+"edpd/temp/atom"_compute_edpd_temp_atom.html,
"fep"_compute_fep.html,
"force/tally"_compute_tally.html,
"heat/flux/tally"_compute_tally.html,
@@ -868,6 +874,7 @@ package"_Section_start.html#start_3.
"smd/ulsph/stress"_compute_smd_ulsph_stress.html,
"smd/vol"_compute_smd_vol.html,
"stress/tally"_compute_tally.html,
+"tdpd/cc/atom"_compute_tdpd_cc_atom.html,
"temp/drude"_compute_temp_drude.html,
"temp/eff"_compute_temp_eff.html,
"temp/deform/eff"_compute_temp_deform_eff.html,
@@ -1024,6 +1031,7 @@ package"_Section_start.html#start_3.
"eam/cd (o)"_pair_eam.html,
"edip (o)"_pair_edip.html,
"edip/multi"_pair_edip.html,
+"edpd"_pair_meso.html,
"eff/cut"_pair_eff.html,
"exp6/rx"_pair_exp6_rx.html,
"gauss/cut"_pair_gauss.html,
@@ -1041,6 +1049,8 @@ package"_Section_start.html#start_3.
"lj/sdk (gko)"_pair_sdk.html,
"lj/sdk/coul/long (go)"_pair_sdk.html,
"lj/sdk/coul/msm (o)"_pair_sdk.html,
+"mdpd"_pair_meso.html,
+"mdpd/rhosum"_pair_meso.html,
"meam/c"_pair_meam.html,
"meam/spline (o)"_pair_meam_spline.html,
"meam/sw/spline"_pair_meam_sw_spline.html,
@@ -1074,6 +1084,7 @@ package"_Section_start.html#start_3.
"sph/taitwater/morris"_pair_sph_taitwater_morris.html,
"srp"_pair_srp.html,
"table/rx"_pair_table_rx.html,
+"tdpd"_pair_meso.html,
"tersoff/table (o)"_pair_tersoff.html,
"thole"_pair_thole.html,
"tip4p/long/soft (o)"_pair_lj_soft.html :tb(c=4,ea=c)
diff --git a/doc/src/Section_packages.txt b/doc/src/Section_packages.txt
index 16864bcdc4..6122dfac78 100644
--- a/doc/src/Section_packages.txt
+++ b/doc/src/Section_packages.txt
@@ -112,7 +112,7 @@ Package, Description, Doc page, Example, Library
"REPLICA"_#REPLICA, multi-replica methods, "Section 6.6.5"_Section_howto.html#howto_5, tad, -
"RIGID"_#RIGID, rigid bodies and constraints, "fix rigid"_fix_rigid.html, rigid, -
"SHOCK"_#SHOCK, shock loading methods, "fix msst"_fix_msst.html, -, -
-"SNAP"_#SNAP, quantum-fitted potential, "pair snap"_pair_snap.html, snap, -
+"SNAP"_#SNAP, quantum-fitted potential, "pair_style snap"_pair_snap.html, snap, -
"SRD"_#SRD, stochastic rotation dynamics, "fix srd"_fix_srd.html, srd, -
"VORONOI"_#VORONOI, Voronoi tesselation, "compute voronoi/atom"_compute_voronoi_atom.html, -, ext :tb(ea=c,ca1=l)
@@ -134,6 +134,7 @@ Package, Description, Doc page, Example, Library
"USER-LB"_#USER-LB, Lattice Boltzmann fluid,"fix lb/fluid"_fix_lb_fluid.html, USER/lb, -
"USER-MANIFOLD"_#USER-MANIFOLD, motion on 2d surfaces,"fix manifoldforce"_fix_manifoldforce.html, USER/manifold, -
"USER-MEAMC"_#USER-MEAMC, modified EAM potential (C++), "pair_style meam/c"_pair_meam.html, meam, -
+"USER-MESO"_#USER-MESO, mesoscale DPD models, "pair_style edpd"_pair_meso.html, USER/meso, -
"USER-MGPT"_#USER-MGPT, fast MGPT multi-ion potentials, "pair_style mgpt"_pair_mgpt.html, USER/mgpt, -
"USER-MISC"_#USER-MISC, single-file contributions, USER-MISC/README, USER/misc, -
"USER-MOLFILE"_#USER-MOLFILE, "VMD"_vmd_home molfile plug-ins,"dump molfile"_dump_molfile.html, -, ext
@@ -1342,7 +1343,7 @@ make machine :pre
[Supporting info:]
src/SNAP: filenames -> commands
-"pair snap"_pair_snap.html
+"pair_style snap"_pair_snap.html
"compute sna/atom"_compute_sna_atom.html
"compute snad/atom"_compute_sna_atom.html
"compute snav/atom"_compute_sna_atom.html
@@ -1556,7 +1557,7 @@ make machine :pre
src/USER-AWPMD: filenames -> commands
src/USER-AWPMD/README
-"pair awpmd/cut"_pair_awpmd.html
+"pair_style awpmd/cut"_pair_awpmd.html
examples/USER/awpmd :ul
:line
@@ -1745,12 +1746,12 @@ src/USER-DPD: filenames -> commands
"fix eos/table/rx"_fix_eos_table_rx.html
"fix shardlow"_fix_shardlow.html
"fix rx"_fix_rx.html
-"pair table/rx"_pair_table_rx.html
-"pair dpd/fdt"_pair_dpd_fdt.html
-"pair dpd/fdt/energy"_pair_dpd_fdt.html
-"pair exp6/rx"_pair_exp6_rx.html
-"pair multi/lucy"_pair_multi_lucy.html
-"pair multi/lucy/rx"_pair_multi_lucy_rx.html
+"pair_style table/rx"_pair_table_rx.html
+"pair_style dpd/fdt"_pair_dpd_fdt.html
+"pair_style dpd/fdt/energy"_pair_dpd_fdt.html
+"pair_style exp6/rx"_pair_exp6_rx.html
+"pair_style multi/lucy"_pair_multi_lucy.html
+"pair_style multi/lucy/rx"_pair_multi_lucy_rx.html
examples/USER/dpd :ul
:line
@@ -1785,8 +1786,8 @@ src/USER-DRUDE/README
"fix drude"_fix_drude.html
"fix drude/transform/*"_fix_drude_transform.html
"compute temp/drude"_compute_temp_drude.html
-"pair thole"_pair_thole.html
-"pair lj/cut/thole/long"_pair_thole.html
+"pair_style thole"_pair_thole.html
+"pair_style lj/cut/thole/long"_pair_thole.html
examples/USER/drude
tools/drude :ul
@@ -1824,8 +1825,8 @@ src/USER-EFF/README
"fix npt/eff"_fix_nh_eff.html
"fix langevin/eff"_fix_langevin_eff.html
"compute temp/eff"_compute_temp_eff.html
-"pair eff/cut"_pair_eff.html
-"pair eff/inline"_pair_eff.html
+"pair_style eff/cut"_pair_eff.html
+"pair_style eff/inline"_pair_eff.html
examples/USER/eff
tools/eff/README
tools/eff
@@ -2155,11 +2156,47 @@ make machine :pre
src/USER-MEAMC: filenames -> commands
src/USER-MEAMC/README
-"pair meam/c"_pair_meam.html
+"pair_style meam/c"_pair_meam.html
examples/meam :ul
:line
+USER-MESO package :link(USER-MESO),h4
+
+[Contents:]
+
+Several extensions of the the dissipative particle dynamics (DPD)
+method. Specifically, energy-conserving DPD (eDPD) that can model
+non-isothermal processes, many-body DPD (mDPD) for simulating
+vapor-liquid coexistence, and transport DPD (tDPD) for modeling
+advection-diffuion-reaction systems. The equations of motion of these
+DPD extensions are integrated through a modified velocity-Verlet (MVV)
+algorithm.
+
+[Author:] Zhen Li (Division of Applied Mathematics, Brown University)
+
+[Install or un-install:]
+
+make yes-user-meso
+make machine :pre
+
+make no-user-meso
+make machine :pre
+
+[Supporting info:]
+
+src/USER-MESO: filenames -> commands
+src/USER-MESO/README
+"atom_style edpd"_atom_style.html
+"pair_style edpd"_pair_meso.html
+"pair_style mdpd"_pair_meso.html
+"pair_style tdpd"_pair_meso.html
+"fix mvv/dpd"_fix_mvv.html
+examples/USER/meso
+http://lammps.sandia.gov/movies.html#mesodpd :ul
+
+:line
+
USER-MOLFILE package :link(USER-MOLFILE),h4
[Contents:]
diff --git a/doc/src/atom_style.txt b/doc/src/atom_style.txt
index 077636dfd1..49d9dde791 100644
--- a/doc/src/atom_style.txt
+++ b/doc/src/atom_style.txt
@@ -13,17 +13,19 @@ atom_style command :h3
atom_style style args :pre
style = {angle} or {atomic} or {body} or {bond} or {charge} or {dipole} or \
- {dpd} or {electron} or {ellipsoid} or {full} or {line} or {meso} or \
- {molecular} or {peri} or {smd} or {sphere} or {tri} or \
- {template} or {hybrid} :ulb,l
+ {dpd} or {edpd} or {mdpd} or {tdpd} or {electron} or {ellipsoid} or \
+ {full} or {line} or {meso} or {molecular} or {peri} or {smd} or \
+ {sphere} or {tri} or {template} or {hybrid} :ulb,l
args = none for any style except the following
- {body} args = bstyle bstyle-args
- bstyle = style of body particles
- bstyle-args = additional arguments specific to the bstyle
- see the "body"_body.html doc page for details
- {template} args = template-ID
- template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command
- {hybrid} args = list of one or more sub-styles, each with their args :pre
+ {body} args = bstyle bstyle-args
+ bstyle = style of body particles
+ bstyle-args = additional arguments specific to the bstyle
+ see the "body"_body.html doc page for details
+ {tdpd} arg = Nspecies
+ Nspecies = # of chemical species
+ {template} arg = template-ID
+ template-ID = ID of molecule template specified in a separate "molecule"_molecule.html command
+ {hybrid} args = list of one or more sub-styles, each with their args :pre
accelerated styles (with same args) = {angle/kk} or {atomic/kk} or {bond/kk} or {charge/kk} or {full/kk} or {molecular/kk} :l
:ule
@@ -36,7 +38,8 @@ atom_style full
atom_style body nparticle 2 10
atom_style hybrid charge bond
atom_style hybrid charge body nparticle 2 5
-atom_style template myMols :pre
+atom_style template myMols
+atom_style tdpd 2 :pre
[Description:]
@@ -74,6 +77,9 @@ quantities.
{charge} | charge | atomic system with charges |
{dipole} | charge and dipole moment | system with dipolar particles |
{dpd} | internal temperature and internal energies | DPD particles |
+{edpd} | temperature and heat capacity | eDPD particles |
+{mdpd} | density | mDPD particles |
+{tdpd} | chemical concentration | tDPD particles |
{electron} | charge and spin and eradius | electronic force field |
{ellipsoid} | shape, quaternion, angular momentum | aspherical particles |
{full} | molecular + charge | bio-molecules |
@@ -145,6 +151,19 @@ properties with internal temperature (dpdTheta), internal conductive
energy (uCond), internal mechanical energy (uMech), and internal
chemical energy (uChem).
+The {edpd} style is for energy-conserving dissipative particle
+dynamics (eDPD) particles which store a temperature (edpd_temp), and
+heat capacity(edpd_cv).
+
+The {mdpd} style is for many-body dissipative particle dynamics (mDPD)
+particles which store a density (rho) for considering
+density-dependent many-body interactions.
+
+The {tdpd} style is for transport dissipative particle dynamics (tDPD)
+particles which store a set of chemical concentration. An integer
+"cc_species" is required to specify the number of chemical species
+involved in a tDPD system.
+
The {meso} style is for smoothed particle hydrodynamics (SPH)
particles which store a density (rho), energy (e), and heat capacity
(cv).
@@ -284,6 +303,11 @@ force fields"_pair_eff.html.
The {dpd} style is part of the USER-DPD package for dissipative
particle dynamics (DPD).
+The {edpd}, {mdpd}, and {tdpd} styles are part of the USER-MESO package
+for energy-conserving dissipative particle dynamics (eDPD), many-body
+dissipative particle dynamics (mDPD), and transport dissipative particle
+dynamics (tDPD), respectively.
+
The {meso} style is part of the USER-SPH package for smoothed particle
hydrodynamics (SPH). See "this PDF
guide"_USER/sph/SPH_LAMMPS_userguide.pdf to using SPH in LAMMPS.
diff --git a/doc/src/compute_edpd_temp_atom.txt b/doc/src/compute_edpd_temp_atom.txt
new file mode 100644
index 0000000000..5b8c8ebd67
--- /dev/null
+++ b/doc/src/compute_edpd_temp_atom.txt
@@ -0,0 +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 edpd/temp/atom command :h3
+
+[Syntax:]
+
+compute ID group-ID edpd/temp/atom :pre
+
+ID, group-ID are documented in "compute"_compute.html command
+edpd/temp/atom = style name of this compute command :ul
+
+[Examples:]
+
+compute 1 all edpd/temp/atom :pre
+
+[Description:]
+
+Define a computation that calculates the per-atom temperature
+for each eDPD particle in a group.
+
+The temperature is a local temperature derived from the internal energy
+of each eDPD particle based on the local equilibrium hypothesis.
+For more details please see "(Espanol1997)"_#Espanol1997 and
+"(Li2014)"_#Li2014a.
+
+[Output info:]
+
+This compute calculates a per-atom vector, which can be accessed by
+any command that uses per-atom values from a compute as input. See
+"Section 6.15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
+
+The per-atom vector values will be in temperature "units"_units.html.
+
+[Restrictions:]
+
+This compute is part of the USER-MESO 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_style edpd"_pair_meso.html
+
+[Default:] none
+
+:line
+
+:link(Espanol1997)
+[(Espanol1997)] Espanol, Europhys Lett, 40(6): 631-636 (1997). DOI:
+10.1209/epl/i1997-00515-8
+
+:link(Li2014a)
+[(Li2014)] Li, Tang, Lei, Caswell, Karniadakis, J Comput Phys, 265:
+113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003.
+
diff --git a/doc/src/compute_tdpd_cc_atom.txt b/doc/src/compute_tdpd_cc_atom.txt
new file mode 100644
index 0000000000..a6a12dc52c
--- /dev/null
+++ b/doc/src/compute_tdpd_cc_atom.txt
@@ -0,0 +1,60 @@
+"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 tdpd/cc/atom command :h3
+
+[Syntax:]
+
+compute ID group-ID tdpd/cc/atom index :pre
+
+ID, group-ID are documented in "compute"_compute.html command
+tdpd/cc/atom = style name of this compute command
+index = index of chemical species (1 to Nspecies) :ul
+
+[Examples:]
+
+compute 1 all tdpd/cc/atom 2 :pre
+
+[Description:]
+
+Define a computation that calculates the per-atom chemical
+concentration of a specified species for each tDPD particle in a
+group.
+
+The chemical concentration of each species is defined as the number of
+molecules carried by a tDPD particle for dilute solution. For more
+details see "(Li2015)"_#Li2015a.
+
+[Output info:]
+
+This compute calculates a per-atom vector, which can be accessed by
+any command that uses per-atom values from a compute as input. See
+"Section 6.15"_Section_howto.html#howto_15 for an overview of
+LAMMPS output options.
+
+The per-atom vector values will be in the units of chemical species
+per unit mass.
+
+[Restrictions:]
+
+This compute is part of the USER-MESO 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_style tdpd"_pair_meso.html
+
+[Default:] none
+
+:line
+
+:link(Li2015a)
+[(Li2015)] Li, Yazdani, Tartakovsky, Karniadakis, J Chem Phys, 143:
+014101 (2015). DOI: 10.1063/1.4923254
+
diff --git a/doc/src/computes.txt b/doc/src/computes.txt
index 5a6ca66c46..c443bfaba2 100644
--- a/doc/src/computes.txt
+++ b/doc/src/computes.txt
@@ -30,6 +30,7 @@ Computes :h1
compute_displace_atom
compute_dpd
compute_dpd_atom
+ compute_edpd_temp_atom
compute_erotate_asphere
compute_erotate_rigid
compute_erotate_sphere
@@ -95,6 +96,7 @@ Computes :h1
compute_sna_atom
compute_stress_atom
compute_tally
+ compute_tdpd_cc_atom
compute_temp
compute_temp_asphere
compute_temp_body
diff --git a/doc/src/fix_dpd_source.txt b/doc/src/fix_dpd_source.txt
new file mode 100644
index 0000000000..b6decc657c
--- /dev/null
+++ b/doc/src/fix_dpd_source.txt
@@ -0,0 +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 edpd/source command :h3
+fix tdpd/source command :h3
+
+[Syntax:]
+
+fix ID group-ID edpd/source keyword values ...
+fix ID group-ID tdpd/source cc_index keyword values ... :pre
+
+ID, group-ID are documented in "fix"_fix.html command :ulb,l
+edpd/source or tdpd/source = style name of this fix command :l
+index (only specified for tdpd/source) = index of chemical species (1 to Nspecies) :l
+keyword = {sphere} or {cuboid} :l
+ {sphere} values = cx,cy,cz,radius,source
+ cx,cy,cz = x,y,z center of spherical domain (distance units)
+ radius = radius of a spherical domain (distance units)
+ source = heat source or concentration source (flux units, see below)
+ {cuboid} values = cx,cy,cz,dLx,dLy,dLz,source
+ cx,cy,cz = x,y,z lower left corner of a cuboid domain (distance units)
+ dLx,dLy,dLz = x,y,z side length of a cuboid domain (distance units)
+ source = heat source or concentration source (flux units, see below) :pre
+:ule
+
+[Examples:]
+
+fix 1 all edpd/source sphere 0.0 0.0 0.0 5.0 0.01
+fix 1 all edpd/source cuboid 0.0 0.0 0.0 20.0 10.0 10.0 -0.01
+fix 1 all tdpd/source 1 sphere 5.0 0.0 0.0 5.0 0.01
+fix 1 all tdpd/source 2 cuboid 0.0 0.0 0.0 20.0 10.0 10.0 0.01 :pre
+
+[Description:]
+
+Fix {edpd/source} adds a heat source as an external heat flux to each
+atom in a spherical or cuboid domain, where the {source} is in units
+of energy/time. Fix {tdpd/source} adds an external concentration
+source of the chemical species specified by {index} as an external
+concentration flux for each atom in a spherical or cuboid domain,
+where the {source} is in units of mole/volume/time.
+
+This command can be used to give an additional heat/concentration
+source term to atoms in a simulation, such as for a simulation of a
+heat conduction with a source term (see Fig.12 in "(Li2014)"_#Li2014b)
+or diffusion with a source term (see Fig.1 in "(Li2015)"_#Li2015b), as
+an analog of a periodic Poiseuille flow problem.
+
+If the {sphere} keyword is used, the {cx,cy,cz,radius} defines a
+spherical domain to apply the source flux to.
+
+If the {cuboid} keyword is used, the {cx,cy,cz,dLx,dLy,dLz} defines a
+cuboid domain to apply the source flux to.
+
+: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 is part of the USER-MESO 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.
+
+Fix {edpd/source} must be used with the "pair_style
+edpd"_pair_meso.html command. Fix {tdpd/source} must be used with the
+"pair_style tdpd"_pair_meso.html command.
+
+[Related commands:]
+
+"pair_style edpd"_pair_meso.html, "pair_style tdpd"_pair_meso.html,
+"compute edpd/temp/atom"_compute_edpd_temp_atom.html, "compute
+tdpd/cc/atom"_compute_tdpd_cc_atom.html
+
+[Default:] none
+
+:line
+
+:link(Li2014b)
+[(Li2014)] Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis,
+"Energy-conserving dissipative particle dynamics with
+temperature-dependent properties", J. Comput. Phys., 265: 113-127
+(2014). DOI: 10.1016/j.jcp.2014.02.003
+
+:link(Li2015b)
+[(Li2015)] Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis,
+"Transport dissipative particle dynamics model for mesoscopic
+advection-diffusion-reaction problems", J. Chem. Phys., 143: 014101
+(2015). DOI: 10.1063/1.4923254
diff --git a/doc/src/fix_mvv_dpd.txt b/doc/src/fix_mvv_dpd.txt
new file mode 100644
index 0000000000..3c1c1a7cba
--- /dev/null
+++ b/doc/src/fix_mvv_dpd.txt
@@ -0,0 +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
+
+fix mvv/dpd command :h3
+fix mvv/edpd command :h3
+fix mvv/tdpd command :h3
+
+[Syntax:]
+
+fix ID group-ID mvv/dpd lambda :pre
+fix ID group-ID mvv/edpd lambda :pre
+fix ID group-ID mvv/tdpd lambda :pre
+
+ID, group-ID are documented in "fix"_fix.html command
+mvv/dpd, mvv/edpd, mvv/tdpd = style name of this fix command
+lambda = (optional) relaxation parameter (unitless) :ul
+
+[Examples:]
+
+fix 1 all mvv/dpd
+fix 1 all mvv/dpd 0.5
+fix 1 all mvv/edpd
+fix 1 all mvv/edpd 0.5
+fix 1 all mvv/tdpd
+fix 1 all mvv/tdpd 0.5 :pre
+
+[Description:]
+
+Perform time integration using the modified velocity-Verlet (MVV)
+algorithm to update position and velocity (fix mvv/dpd), or position,
+velocity and temperature (fix mvv/edpd), or position, velocity and
+concentration (fix mvv/tdpd) for particles in the group each timestep.
+
+The modified velocity-Verlet (MVV) algorithm aims to improve the
+stability of the time integrator by using an extrapolated version of
+the velocity for the force evaluation:
+
+:c,image(Eqs/fix_mvv_dpd.jpg)
+
+where the parameter λ depends on the
+specific choice of DPD parameters, and needs to be tuned on a
+case-by-case basis. Specification of a {lambda} value is opttional.
+If specified, the setting must be from 0.0 to 1.0. If not specified,
+a default value of 0.5 is used, which effectively reproduces the
+standard velocity-Verlet (VV) scheme. For more details, see
+"Groot"_#Groot2.
+
+Fix {mvv/dpd} updates the position and velocity of each atom. It can
+be used with the "pair_style mdpd"_pair_meso.html command or other
+pair styles such as "pair dpd"_pair_dpd.html.
+
+Fix {mvv/edpd} updates the per-atom temperature, in addition to
+position and velocity, and must be used with the "pair_style
+edpd"_pair_meso.html command.
+
+Fix {mvv/tdpd} updates the per-atom chemical concentration, in
+addition to position and velocity, and must be used with the
+"pair_style tdpd"_pair_meso.html command.
+
+: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 is part of the USER-MESO 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_style mdpd"_pair_meso.html, "pair_style edpd"_pair_meso.html,
+"pair_style tdpd"_pair_meso.html
+
+[Default:]
+
+The default value for the optional {lambda} parameter is 0.5.
+
+:line
+
+:link(Groot2)
+[(Groot)] Groot and Warren, J Chem Phys, 107: 4423-4435 (1997). DOI:
+10.1063/1.474784
+
diff --git a/doc/src/fixes.txt b/doc/src/fixes.txt
index 3dc5e77e14..7000a66c51 100644
--- a/doc/src/fixes.txt
+++ b/doc/src/fixes.txt
@@ -33,6 +33,7 @@ Fixes :h1
fix_drude
fix_drude_transform
fix_dpd_energy
+ fix_dpd_source
fix_dt_reset
fix_efield
fix_ehex
@@ -71,6 +72,7 @@ Fixes :h1
fix_move
fix_mscg
fix_msst
+ fix_mvv_dpd
fix_neb
fix_nh
fix_nh_eff
diff --git a/doc/src/lammps.book b/doc/src/lammps.book
index 76b6743657..37587937e7 100644
--- a/doc/src/lammps.book
+++ b/doc/src/lammps.book
@@ -156,6 +156,7 @@ fix_controller.html
fix_deform.html
fix_deposit.html
fix_dpd_energy.html
+fix_dpd_source.html
fix_drag.html
fix_drude.html
fix_drude_transform.html
@@ -197,6 +198,7 @@ fix_momentum.html
fix_move.html
fix_mscg.html
fix_msst.html
+fix_mvv_dpd.html
fix_neb.html
fix_nh.html
fix_nh_eff.html
@@ -315,6 +317,7 @@ compute_dipole_chunk.html
compute_displace_atom.html
compute_dpd.html
compute_dpd_atom.html
+compute_edpd_temp_atom.html
compute_erotate_asphere.html
compute_erotate_rigid.html
compute_erotate_sphere.html
@@ -380,6 +383,7 @@ compute_smd_vol.html
compute_sna_atom.html
compute_stress_atom.html
compute_tally.html
+compute_tdpd_cc_atom.html
compute_temp.html
compute_temp_asphere.html
compute_temp_body.html
@@ -457,6 +461,7 @@ pair_mdf.html
pair_meam.html
pair_meam_spline.html
pair_meam_sw_spline.html
+pair_meso.html
pair_mgpt.html
pair_mie.html
pair_momb.html
@@ -644,4 +649,3 @@ USER/atc/man_unfix_flux.html
USER/atc/man_unfix_nodes.html
USER/atc/man_write_atom_weights.html
USER/atc/man_write_restart.html
-
diff --git a/doc/src/pair_dpd.txt b/doc/src/pair_dpd.txt
index 9dd204ad2d..8d194bb092 100644
--- a/doc/src/pair_dpd.txt
+++ b/doc/src/pair_dpd.txt
@@ -36,7 +36,7 @@ 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.
+(DPD) following the exposition in "(Groot)"_#Groot1.
Style {dpd/tstat} invokes a DPD thermostat on pairwise interactions,
which is equivalent to the non-conservative portion of the DPD force
@@ -196,7 +196,7 @@ langevin"_fix_langevin.html, "pair_style srp"_pair_srp.html
:line
-:link(Groot)
+:link(Groot1)
[(Groot)] Groot and Warren, J Chem Phys, 107, 4423-35 (1997).
:link(Afshar)
diff --git a/doc/src/pair_meso.txt b/doc/src/pair_meso.txt
new file mode 100644
index 0000000000..bcdf717d68
--- /dev/null
+++ b/doc/src/pair_meso.txt
@@ -0,0 +1,277 @@
+"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 edpd command :h3
+pair_style mdpd command :h3
+pair_style mdpd/rhosum command :h3
+pair_style tdpd command :h3
+
+[Syntax:]
+
+pair_style style args :pre
+
+style = {edpd} or {mdpd} or {mdpd/rhosum} or {tdpd} :ulb,l
+args = list of arguments for a particular style :l
+ {edpd} args = cutoff seed
+ cutoff = global cutoff for eDPD interactions (distance units)
+ seed = random # seed (integer) (if <= 0, eDPD will use current time as the seed)
+ {mdpd} args = T cutoff seed
+ T = temperature (temperature units)
+ cutoff = global cutoff for mDPD interactions (distance units)
+ seed = random # seed (integer) (if <= 0, mDPD will use current time as the seed)
+ {mdpd/rhosum} args =
+ {tdpd} args = T cutoff seed
+ T = temperature (temperature units)
+ cutoff = global cutoff for tDPD interactions (distance units)
+ seed = random # seed (integer) (if <= 0, tDPD will use current time as the seed) :pre
+:ule
+
+[Examples:]
+
+pair_style edpd 1.58 9872598
+pair_coeff * * 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.42E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00 :pre
+
+pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 65689
+pair_coeff 1 1 mdpd/rhosum 0.75
+pair_coeff 1 1 mdpd -40.0 25.0 18.0 1.0 0.75 :pre
+
+pair_style tdpd 1.0 1.58 935662
+pair_coeff * * 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0 :pre
+
+[Description:]
+
+The {edpd} style computes the pairwise interactions and heat fluxes
+for eDPD particles following the formulations in
+"(Li2014_JCP)"_#Li2014_JCP and "Li2015_CC"_#Li2015_CC. The time
+evolution of an eDPD particle is governed by the conservation of
+momentum and energy given by
+
+:c,image(Eqs/pair_edpd_gov.jpg)
+
+where the three components of Fi
+including the conservative force FijC, dissipative force FijD and random force FijR are expressed as
+
+:c,image(Eqs/pair_edpd_force.jpg)
+
+in which the exponent of the weighting function s can be defined as a temperature-dependent
+variable. The heat flux between particles accounting for the
+collisional heat flux qC, viscous
+heat flux qV, and random heat flux
+qR are given by
+
+:c,image(Eqs/pair_edpd_heat.jpg)
+
+where the mesoscopic heat friction κ is given by
+
+:c,image(Eqs/pair_edpd_kappa.jpg)
+
+with υ being the kinematic
+viscosity. For more details, see Eq.(15) in "(Li2014_JCP)"_#Li2014_JCP.
+
+The following coefficients must be defined in eDPD system for each
+pair of atom types via the "pair_coeff"_pair_coeff.html command as in
+the examples above.
+
+A (force units)
+gamma (force/velocity units)
+power_f (positive real)
+cutoff (distance units)
+kappa (thermal conductivity units)
+power_T (positive real)
+cutoff_T (distance units)
+optional keyword = power or kappa :ul
+
+The keyword {power} or {kappa} is optional. Both "power" and "kappa"
+require 4 parameters c1, c2,
+c4, c4 showing the temperature dependence
+of the exponent
s(T) =
+power_f*(1+c1*(T-1)+c2*(T-1)2
++c3*(T-1)3+c4*(T-1)4)
+and of the mesoscopic heat friction
+sT(T) =
+kappa*(1+c1*(T-1)+c2*(T-1)2
++c3*(T-1)3+c4*(T-1)4)
+If the keyword {power} or {kappa} is not specified, the eDPD system
+will use constant power_f and kappa, which is independent to
+temperature changes.
+
+:line
+
+The {mdpd/rhosum} style computes the local particle mass density rho
+for mDPD particles by kernel function interpolation.
+
+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.
+
+cutoff (distance units) :ul
+
+:line
+
+The {mdpd} style computes the many-body interactions between mDPD
+particles following the formulations in
+"(Li2013_POF)"_#Li2013_POF. The dissipative and random forces are in
+the form same as the classical DPD, but the conservative force is
+local density dependent, which are given by
+
+:c,image(Eqs/pair_mdpd_force.jpg)
+
+where the first term in FC with a
+negative coefficient A < 0 stands for an attractive force within an
+interaction range rc, and the second
+term with B > 0 is the density-dependent repulsive force within an
+interaction range rd.
+
+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.
+
+A (force units)
+B (force units)
+gamma (force/velocity units)
+cutoff_c (distance units)
+cutoff_d (distance units) :ul
+
+:line
+
+The {tdpd} style computes the pairwise interactions and chemical
+concentration fluxes for tDPD particles following the formulations in
+"(Li2015_JCP)"_#Li2015_JCP. The time evolution of a tDPD particle is
+governed by the conservation of momentum and concentration given by
+
+:c,image(Eqs/pair_tdpd_gov.jpg)
+
+where the three components of Fi
+including the conservative force FijC, dissipative force FijD and random force FijR are expressed as
+
+:c,image(Eqs/pair_tdpd_force.jpg)
+
+The concentration flux between two tDPD particles includes the Fickian
+flux QijD and random flux
+QijR, which are given by
+
+:c,image(Eqs/pair_tdpd_flux.jpg)
+
+where the parameters kappa and epsilon determine the strength of the
+Fickian and random fluxes. ms
+is the mass of a single solute molecule. In general, ms is much smaller than the mass of
+a tDPD particle m. For more details, see
+"(Li2015_JCP)"_#Li2015_JCP.
+
+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.
+
+A (force units)
+gamma (force/velocity units)
+power_f (positive real)
+cutoff (distance units)
+cutoff_CC (distance units)
+kappa_i (diffusivity units)
+epsilon_i (diffusivity units)
+power_cc_i (positive real) :ul
+
+The last 3 values must be repeated Nspecies times, so that values for
+each of the Nspecies chemical species are specified, as indicated by
+the "I" suffix. In the first pair_coeff example above for pair_style
+tdpd, Nspecies = 1. In the second example, Nspecies = 2, so 3
+additional coeffs are specified (for species 2).
+
+:line
+
+[Example scripts]
+
+There are example scripts for using all these pair styles in
+examples/USER/meso. The example for an eDPD simulation models heat
+conduction with source terms analog of periodic Poiseuille flow
+problem. The setup follows Fig.12 in "(Li2014_JCP)"_#Li2014_JCP. The
+output of the short eDPD simulation (about 2 minutes on a single core)
+gives a temperature and density profiles as
+
+:c,image(JPG/examples_edpd.jpg)
+
+The example for a mDPD simulation models the oscillations of a liquid
+droplet started from a liquid film. The mDPD parameters are adopted
+from "(Li2013_POF)"_#Li2013_POF. The short mDPD run (about 2 minutes
+on a single core) generates a particle trajectory which can
+be visualized as follows.
+
+:c,image(JPG/examples_mdpd_first.jpg,JPG/examples_mdpd.gif)
+:c,image(JPG/examples_mdpd_last.jpg)
+
+The first image is the initial state of the simulation. If you
+click it a GIF movie should play in your browser. The second image
+is the final state of the simulation.
+
+The example for a tDPD simulation computes the effective diffusion
+coefficient of a tDPD system using a method analogous to the periodic
+Poiseuille flow. The tDPD system is specified with two chemical
+species, and the setup follows Fig.1 in
+"(Li2015_JCP)"_#Li2015_JCP. The output of the short tDPD simulation
+(about one and a half minutes on a single core) gives the
+concentration profiles of the two chemical species as
+
+:c,image(JPG/examples_tdpd.jpg)
+
+:line
+
+[Mixing, shift, table, tail correction, restart, rRESPA info]:
+
+The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not support
+mixing. Thus, coefficients for all I,J pairs must be specified explicitly.
+
+The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not support
+the "pair_modify"_pair_modify.html shift, table, and tail options.
+
+The styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} do not write
+information to "binary restart files"_restart.html. Thus, you need
+to re-specify the pair_style and pair_coeff commands in an input script
+that reads a restart file.
+
+[Restrictions:]
+
+The pair styles {edpd}, {mdpd}, {mdpd/rhosum} and {tdpd} are part of
+the USER-MESO 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, "fix mvv/dpd"_fix_mvv_dpd.html,
+"fix mvv/edpd"_fix_mvv_dpd.html, "fix mvv/tdpd"_fix_mvv_dpd.html,
+"fix edpd/source"_fix_dpd_source.html, "fix tdpd/source"_fix_dpd_source.html,
+"compute edpd/temp/atom"_compute_edpd_temp_atom.html,
+"compute tdpd/cc/atom"_compute_tdpd_cc_atom.html
+
+[Default:] none
+
+:line
+
+:link(Li2014_JCP)
+[(Li2014_JCP)] Li, Tang, Lei, Caswell, Karniadakis, J Comput Phys,
+265: 113-127 (2014). DOI: 10.1016/j.jcp.2014.02.003.
+
+:link(Li2015_CC)
+[(Li2015_CC)] Li, Tang, Li, Karniadakis, Chem Commun, 51: 11038-11040
+(2015). DOI: 10.1039/C5CC01684C.
+
+:link(Li2013_POF)
+[(Li2013_POF)] Li, Hu, Wang, Ma, Zhou, Phys Fluids, 25: 072103 (2013).
+DOI: 10.1063/1.4812366.
+
+:link(Li2015_JCP)
+[(Li2015_JCP)] Li, Yazdani, Tartakovsky, Karniadakis, J Chem Phys,
+143: 014101 (2015). DOI: 10.1063/1.4923254.
diff --git a/doc/src/pair_snap.txt b/doc/src/pair_snap.txt
index fa90dc34e9..593765aa63 100644
--- a/doc/src/pair_snap.txt
+++ b/doc/src/pair_snap.txt
@@ -10,8 +10,7 @@ pair_style snap command :h3
[Syntax:]
-pair_style snap
-:pre
+pair_style snap :pre
[Examples:]
@@ -20,17 +19,16 @@ pair_coeff * * InP.snapcoeff In P InP.snapparam In In P P :pre
[Description:]
-Pair style {snap} computes interactions
-using the spectral neighbor analysis potential (SNAP)
-"(Thompson)"_#Thompson20142. Like the GAP framework of Bartok et al.
-"(Bartok2010)"_#Bartok20102, "(Bartok2013)"_#Bartok2013
-which uses bispectrum components
+Pair style {snap} computes interactions using the spectral
+neighbor analysis potential (SNAP) "(Thompson)"_#Thompson20142.
+Like the GAP framework of Bartok et al. "(Bartok2010)"_#Bartok20102,
+"(Bartok2013)"_#Bartok2013 which uses bispectrum components
to characterize the local neighborhood of each atom
in a very general way. The mathematical definition of the
bispectrum calculation used by SNAP is identical
to that used by "compute sna/atom"_compute_sna_atom.html.
In SNAP, the total energy is decomposed into a sum over
-atom energies. The energy of atom {i } is
+atom energies. The energy of atom {i} is
expressed as a weighted sum over bispectrum components.
:c,image(Eqs/pair_snap.jpg)
diff --git a/doc/src/pairs.txt b/doc/src/pairs.txt
index 2c1b20f4d3..ec21b7a02e 100644
--- a/doc/src/pairs.txt
+++ b/doc/src/pairs.txt
@@ -58,6 +58,7 @@ Pair Styles :h1
pair_meam
pair_meam_spline
pair_meam_sw_spline
+ pair_meso
pair_mgpt
pair_mie
pair_momb
diff --git a/doc/src/read_data.txt b/doc/src/read_data.txt
index a8aca53693..8c9aa02e22 100644
--- a/doc/src/read_data.txt
+++ b/doc/src/read_data.txt
@@ -374,10 +374,9 @@ needed if new bonds (angles, dihedrals, impropers) will be added to
the system when a simulation runs, e.g. by using the "fix
bond/create"_fix_bond_create.html command. Using this header flag
is deprecated; please use the {extra/bond/per/atom} keyword (and
-correspondingly for angles, dihedrals and impropers) in the
-read_data command instead. Either will pre-allocate space in LAMMPS
- data structures for storing the new bonds (angles,
-dihedrals, impropers).
+correspondingly for angles, dihedrals and impropers) in the read_data
+command instead. Either will pre-allocate space in LAMMPS data
+structures for storing the new bonds (angles, dihedrals, impropers).
The "extra special per atom" setting is typically only needed if new
bonds/angles/etc will be added to the system, e.g. by using the "fix
@@ -547,6 +546,9 @@ 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
dpd: atom-ID atom-type theta x y z
+edpd: atom-ID atom-type edpd_temp edpd_cv x y z
+mdpd: atom-ID atom-type x y z
+tdpd: atom-ID atom-type x y z cc1 cc2 ... ccNspecies
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
@@ -566,12 +568,15 @@ The per-atom values have these meanings and units, listed alphabetically:
atom-ID = integer ID of atom
atom-type = type of atom (1-Ntype)
bodyflag = 1 for body particles, 0 for point particles
+cc = chemical concentration for tDPD particles for each species (mole/volume units)
contact-radius = ??? (distance units)
cs_re,cs_im = real/imaginary parts of wavepacket coefficients
cv = heat capacity (need units) for SPH particles
density = density of particle (mass/distance^3 or mass/distance^2 or mass/distance units, depending on dimensionality of particle)
diameter = diameter of spherical atom (distance units)
e = energy (need units) for SPH particles
+edpd_temp = temperature for eDPD particles (temperature units)
+edpd_cv = volumetric heat capacity for eDPD particles (energy/temperature/volume units)
ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles
eradius = electron radius (or fixed-core radius)
etag = integer ID of electron that each wavepacket belongs to
diff --git a/doc/src/set.txt b/doc/src/set.txt
index 14460c9741..4757d1c575 100644
--- a/doc/src/set.txt
+++ b/doc/src/set.txt
@@ -24,7 +24,7 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \
{bond} or {angle} or {dihedral} or {improper} or \
{meso/e} or {meso/cv} or {meso/rho} or \
{smd/contact/radius} or {smd/mass/density} or {dpd/theta} or \
- {i_name} or {d_name} :l
+ {edpd/temp} or {edpd/cv} or {cc} or {i_name} or {d_name} :l
{type} value = atom type
value can be an atom-style variable (see below)
{type/fraction} values = type fraction seed
@@ -98,6 +98,13 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \
{dpd/theta} value = internal temperature of DPD particles (temperature units)
value can be an atom-style variable (see below)
value can be NULL which sets internal temp of each particle to KE temp
+ {edpd/temp} value = temperature of eDPD particles (temperature units)
+ value can be an atom-style variable (see below)
+ {edpd/cv} value = volumetric heat capacity of eDPD particles (energy/temperature/volume units)
+ value can be an atom-style variable (see below)
+ {cc} values = index cc
+ index = index of a chemical species (1 to Nspecies)
+ cc = chemical concentration of tDPD particles for a species (mole/volume units)
{i_name} value = value for custom integer vector with name
{d_name} value = value for custom floating-point vector with name :pre
:ule
@@ -418,6 +425,19 @@ value >= 0.0, the internal temperature is set to that value. If it is
< 0.0, the computation of Tkin is performed and the internal
temperature is set to that value.
+Keywords {edpd/temp} and {edpd/cv} set the temperature and volumetric
+heat capacity of an eDPD particle as defined by the USER-MESO package.
+Currently, only "atom_style edpd"_atom_style.html defines particles
+with these attributes. The values for the temperature and heat
+capacity must be positive.
+
+Keyword {cc} sets the chemical concentration of a tDPD particle for a
+specified species as defined by the USER-MESO package. Currently, only
+"atom_style tdpd"_atom_style.html defines particles with this
+attribute. An integer for "index" selects a chemical species (1 to
+Nspecies) where Nspecies is set by the atom_style command. The value
+for the chemical concentration must be >= 0.0.
+
Keywords {i_name} and {d_name} refer to custom integer and
floating-point properties that have been added to each atom via the
"fix property/atom"_fix_property_atom.html command. When that command
diff --git a/examples/USER/meso/README b/examples/USER/meso/README
new file mode 100644
index 0000000000..4accc7ba01
--- /dev/null
+++ b/examples/USER/meso/README
@@ -0,0 +1,40 @@
+This directory contains input scripts for performing
+simulations with these models:
+
+eDPD - energy-conserving dissipative particle dynamics
+mDPD - many-body dissipative particle dynamics
+tDPD - transport dissipative particle dynamics
+
+1) eDPD: The input script in.mdpd is an example simulation of
+measuring the thermal conductivity by heat conduction analog of
+periodic Poiseuille flow. The initial eDPD system is randomly filled
+by many eDPD particles, and a set command "edpd/temp" gives the
+initial temperature and a set command "edpd/cv" gives the heat
+capacity of eDPD particles. A non-contact heat source/sink term is
+applied by a fix command "edpd/source". A compute command
+"edpd/temp/atom" obtain the temperature on each eDPD particle. The
+simulation will generate a file named "temp.profile" showing the
+temperature profile. For details please see online LAMMPS
+documentation and Fig.12 in the paper Z. Li, et al. J Comput Phys,
+2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003
+
+2) mDPD: The input script "in.mdpd" is an example simulation of
+oscillations of a free liquid droplet. The initial configuration is a
+liquid film whose particles are in a fcc lattice created by the
+command "create atoms". Then the liquid film has a tendency to form a
+spherical droplet under the effect of surface tension. For details
+please see online LAMMPS documentation and the paper Z. Li, et
+al. Phys Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366
+
+3) tDPD: The input script in.tdpd is an example simulation of
+computing the effective diffusion coefficient of a tDPD system using a
+method analogous to the periodic Poiseuille flow. Command "atom_style
+tdpd 2" specifies the tDPD system with two chemical species. The
+initial tDPD system is randomly filled by many tDPD particles, and a
+set "cc" command gives initial concentration for each chemical
+species. Fix commands "tdpd/source" add source terms and compute
+commands "tdpd/cc/atom" obtain the chemical concentration on each tDPD
+particle. The simulation will generate a file named "cc.profile"
+showing the concentration profiles of the two chemical species. For
+details please see online LAMMPS documentation and Fig.1 in the paper
+Z. Li, et al. J Chem Phys, 2015, 143: 014101. DOI: 10.1063/1.4923254
diff --git a/examples/USER/meso/edpd/in.edpd b/examples/USER/meso/edpd/in.edpd
new file mode 100644
index 0000000000..316099bce3
--- /dev/null
+++ b/examples/USER/meso/edpd/in.edpd
@@ -0,0 +1,54 @@
+########################################################################
+### Heat conduction analog of periodic Poiseuille flow problem ###
+### using energy-conserving DPD (eDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### mDPD system setup follows Fig.12 in the publication: ###
+### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ###
+### "Energy-conserving dissipative particle dynamics with ###
+### temperature-dependent properties". J. Comput. Phys., ###
+### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style edpd
+
+region edpd block -10 10 -10 10 -5 5 units box
+create_box 1 edpd
+create_atoms 1 random 16000 276438 NULL
+mass 1 1.0
+set atom * edpd/temp 1.0
+set atom * edpd/cv 1.0E5
+
+pair_style edpd 1.58 9872598
+#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 &
+ power 10.54 -3.66 3.44 -4.10 &
+ kappa -0.44 -3.21 5.04 0.00
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/edpd 0.5
+fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+
+timestep 0.01
+run 500
+reset_timestep 0
+
+compute temp all edpd/temp/atom
+compute ccT all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile
+
+run 500
diff --git a/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1 b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1
new file mode 100644
index 0000000000..af975f877c
--- /dev/null
+++ b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.1
@@ -0,0 +1,142 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+### Heat conduction analog of periodic Poiseuille flow problem ###
+### using energy-conserving DPD (eDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### mDPD system setup follows Fig.12 in the publication: ###
+### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ###
+### "Energy-conserving dissipative particle dynamics with ###
+### temperature-dependent properties". J. Comput. Phys., ###
+### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style edpd
+
+region edpd block -10 10 -10 10 -5 5 units box
+create_box 1 edpd
+Created orthogonal box = (-10 -10 -5) to (10 10 5)
+ 1 by 1 by 1 MPI processor grid
+create_atoms 1 random 16000 276438 NULL
+Created 16000 atoms
+mass 1 1.0
+set atom * edpd/temp 1.0
+ 16000 settings made for edpd/temp
+set atom * edpd/cv 1.0E5
+ 16000 settings made for edpd/cv
+
+pair_style edpd 1.58 9872598
+#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/edpd 0.5
+fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+
+timestep 0.01
+run 500
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.78
+ ghost atom cutoff = 1.78
+ binsize = 0.89, bins = 23 23 12
+ 1 neighbor lists, perpetual/occasional/extra = 1 0 0
+ (1) pair edpd, perpetual
+ attributes: half, newton on
+ pair build: half/bin/atomonly/newton
+ stencil: half/bin/3d/newton
+ bin: standard
+Per MPI rank memory allocation (min/avg/max) = 11.64 | 11.64 | 11.64 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 48.948932 0 50.448838 201.73366
+ 100 1.0069712 43.754293 0 45.264656 199.5369
+ 200 0.98667561 43.716052 0 45.195973 196.72854
+ 300 1.0036944 43.706299 0 45.211746 195.35714
+ 400 1.0024228 43.697014 0 45.200554 197.0062
+ 500 0.99968161 43.687445 0 45.186873 193.80596
+Loop time of 80.7995 on 1 procs for 500 steps with 16000 atoms
+
+Performance: 5346.567 tau/day, 6.188 timesteps/s
+99.9% CPU use with 1 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 75.106 | 75.106 | 75.106 | 0.0 | 92.95
+Neigh | 4.9836 | 4.9836 | 4.9836 | 0.0 | 6.17
+Comm | 0.31199 | 0.31199 | 0.31199 | 0.0 | 0.39
+Output | 0.00048232 | 0.00048232 | 0.00048232 | 0.0 | 0.00
+Modify | 0.29985 | 0.29985 | 0.29985 | 0.0 | 0.37
+Other | | 0.09751 | | | 0.12
+
+Nlocal: 16000 ave 16000 max 16000 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 14091 ave 14091 max 14091 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 749111 ave 749111 max 749111 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 749111
+Ave neighs/atom = 46.8194
+Neighbor list builds = 181
+Dangerous builds = 0
+reset_timestep 0
+
+compute temp all edpd/temp/atom
+compute ccT all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile
+
+run 500
+Per MPI rank memory allocation (min/avg/max) = 12.14 | 12.14 | 12.14 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 0.99968161 43.687397 0 45.186825 196.38426
+ 100 1.0041443 43.668196 0 45.174318 195.38066
+ 200 0.99628392 43.666173 0 45.160505 197.84675
+ 300 1.0029116 43.66224 0 45.166513 199.67414
+ 400 0.99922193 43.64406 0 45.142799 196.94404
+ 500 0.99355431 43.623266 0 45.113505 195.94136
+Loop time of 80.7742 on 1 procs for 500 steps with 16000 atoms
+
+Performance: 5348.242 tau/day, 6.190 timesteps/s
+99.9% CPU use with 1 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 75.073 | 75.073 | 75.073 | 0.0 | 92.94
+Neigh | 4.8786 | 4.8786 | 4.8786 | 0.0 | 6.04
+Comm | 0.31086 | 0.31086 | 0.31086 | 0.0 | 0.38
+Output | 0.00045919 | 0.00045919 | 0.00045919 | 0.0 | 0.00
+Modify | 0.4139 | 0.4139 | 0.4139 | 0.0 | 0.51
+Other | | 0.09731 | | | 0.12
+
+Nlocal: 16000 ave 16000 max 16000 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 14091 ave 14091 max 14091 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 749667 ave 749667 max 749667 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 749667
+Ave neighs/atom = 46.8542
+Neighbor list builds = 178
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:02:41
diff --git a/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4 b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4
new file mode 100644
index 0000000000..21206d38c6
--- /dev/null
+++ b/examples/USER/meso/edpd/log.16Aug17.edpd.g++.4
@@ -0,0 +1,142 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+### Heat conduction analog of periodic Poiseuille flow problem ###
+### using energy-conserving DPD (eDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### mDPD system setup follows Fig.12 in the publication: ###
+### Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. ###
+### "Energy-conserving dissipative particle dynamics with ###
+### temperature-dependent properties". J. Comput. Phys., ###
+### 2014, 265: 113-127. DOI: 10.1016/j.jcp.2014.02.003 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style edpd
+
+region edpd block -10 10 -10 10 -5 5 units box
+create_box 1 edpd
+Created orthogonal box = (-10 -10 -5) to (10 10 5)
+ 2 by 2 by 1 MPI processor grid
+create_atoms 1 random 16000 276438 NULL
+Created 16000 atoms
+mass 1 1.0
+set atom * edpd/temp 1.0
+ 16000 settings made for edpd/temp
+set atom * edpd/cv 1.0E5
+ 16000 settings made for edpd/cv
+
+pair_style edpd 1.58 9872598
+#pair_coeff 1 1 18.75 4.5 0.41 1.58 1.45E-5 2.0 1.58
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.41E-5 2.0 1.58 power 10.54 -3.66 3.44 -4.10 kappa -0.44 -3.21 5.04 0.00
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/edpd 0.5
+fix upper all edpd/source cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower all edpd/source cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+
+timestep 0.01
+run 500
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.78
+ ghost atom cutoff = 1.78
+ binsize = 0.89, bins = 23 23 12
+ 1 neighbor lists, perpetual/occasional/extra = 1 0 0
+ (1) pair edpd, perpetual
+ attributes: half, newton on
+ pair build: half/bin/atomonly/newton
+ stencil: half/bin/3d/newton
+ bin: standard
+Per MPI rank memory allocation (min/avg/max) = 4.969 | 4.979 | 4.985 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 48.948932 0 50.448838 199.51547
+ 100 1.0106415 43.744371 0 45.260239 196.39598
+ 200 1.0053215 43.714413 0 45.222301 195.35298
+ 300 0.99886399 43.713356 0 45.211559 196.74821
+ 400 1.0035264 43.699086 0 45.204282 195.47446
+ 500 1.0025285 43.698051 0 45.20175 197.27042
+Loop time of 21.165 on 4 procs for 500 steps with 16000 atoms
+
+Performance: 20411.046 tau/day, 23.624 timesteps/s
+99.9% CPU use with 4 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 18.713 | 19.101 | 19.41 | 6.0 | 90.25
+Neigh | 1.2687 | 1.2925 | 1.3177 | 1.5 | 6.11
+Comm | 0.33013 | 0.66337 | 1.0747 | 34.3 | 3.13
+Output | 0.00023484 | 0.00028092 | 0.00036526 | 0.0 | 0.00
+Modify | 0.073931 | 0.075277 | 0.076306 | 0.3 | 0.36
+Other | | 0.03227 | | | 0.15
+
+Nlocal: 4000 ave 4067 max 3930 min
+Histogram: 1 1 0 0 0 0 0 0 0 2
+Nghost: 5997.5 ave 6052 max 5943 min
+Histogram: 1 0 1 0 0 0 0 1 0 1
+Neighs: 187388 ave 193157 max 181221 min
+Histogram: 1 1 0 0 0 0 0 0 0 2
+
+Total # of neighbors = 749552
+Ave neighs/atom = 46.847
+Neighbor list builds = 181
+Dangerous builds = 0
+reset_timestep 0
+
+compute temp all edpd/temp/atom
+compute ccT all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 500 500 ccT c_temp density/number norm sample file temp.profile
+
+run 500
+Per MPI rank memory allocation (min/avg/max) = 5.221 | 5.23 | 5.236 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1.0025285 43.69801 0 45.201708 194.00452
+ 100 0.9885969 43.679927 0 45.16273 196.28442
+ 200 1.0028463 43.663067 0 45.167242 198.25592
+ 300 1.0027516 43.648817 0 45.152851 198.82226
+ 400 0.99695312 43.641469 0 45.136805 197.97499
+ 500 0.98202292 43.627163 0 45.100105 199.16319
+Loop time of 21.576 on 4 procs for 500 steps with 16000 atoms
+
+Performance: 20022.203 tau/day, 23.174 timesteps/s
+99.8% CPU use with 4 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 18.438 | 19.121 | 19.812 | 14.1 | 88.62
+Neigh | 1.2568 | 1.2885 | 1.325 | 2.5 | 5.97
+Comm | 0.29482 | 1.0219 | 1.7352 | 63.9 | 4.74
+Output | 0.00027728 | 0.00029719 | 0.0003531 | 0.0 | 0.00
+Modify | 0.11153 | 0.11265 | 0.1135 | 0.2 | 0.52
+Other | | 0.03194 | | | 0.15
+
+Nlocal: 4000 ave 4092 max 3899 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+Nghost: 5974 ave 6019 max 5915 min
+Histogram: 1 0 0 1 0 0 0 0 0 2
+Neighs: 187414 ave 196149 max 178418 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+
+Total # of neighbors = 749658
+Ave neighs/atom = 46.8536
+Neighbor list builds = 181
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:00:42
diff --git a/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1 b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1
new file mode 100644
index 0000000000..469b550258
--- /dev/null
+++ b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.1
@@ -0,0 +1,24 @@
+# Chunk-averaged data for fix stat and group density/number
+# Timestep Number-of-chunks Total-count
+# Chunk Coord1 Ncount c_temp density/number
+500 20 16000
+ 1 -9.5 801.636 0.986368 4.00818
+ 2 -8.5 809.788 0.966281 4.04894
+ 3 -7.5 819.754 0.952764 4.09877
+ 4 -6.5 820.364 0.944592 4.10182
+ 5 -5.5 826.146 0.940968 4.13073
+ 6 -4.5 819.52 0.941415 4.0976
+ 7 -3.5 815.182 0.945887 4.07591
+ 8 -2.5 817.168 0.95487 4.08584
+ 9 -1.5 817.282 0.969225 4.08641
+ 10 -0.5 804.204 0.989552 4.02102
+ 11 0.5 793.266 1.01015 3.96633
+ 12 1.5 789.056 1.0308 3.94528
+ 13 2.5 784.344 1.04568 3.92172
+ 14 3.5 780.592 1.05508 3.90296
+ 15 4.5 772.218 1.05968 3.86109
+ 16 5.5 776.968 1.06003 3.88484
+ 17 6.5 780.858 1.05612 3.90429
+ 18 7.5 786.174 1.04752 3.93087
+ 19 8.5 788.922 1.03347 3.94461
+ 20 9.5 796.558 1.01278 3.98279
diff --git a/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4 b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4
new file mode 100644
index 0000000000..1c50a9b6e5
--- /dev/null
+++ b/examples/USER/meso/edpd/temp.profile.16Aug17.edpd.g++.4
@@ -0,0 +1,24 @@
+# Chunk-averaged data for fix stat and group density/number
+# Timestep Number-of-chunks Total-count
+# Chunk Coord1 Ncount c_temp density/number
+500 20 16000
+ 1 -9.5 801.642 0.986089 4.00821
+ 2 -8.5 819.168 0.966072 4.09584
+ 3 -7.5 817.382 0.952718 4.08691
+ 4 -6.5 818 0.944633 4.09
+ 5 -5.5 817.806 0.941105 4.08903
+ 6 -4.5 826.11 0.941499 4.13055
+ 7 -3.5 821.946 0.945922 4.10973
+ 8 -2.5 816.202 0.954889 4.08101
+ 9 -1.5 813.202 0.969281 4.06601
+ 10 -0.5 798.904 0.989463 3.99452
+ 11 0.5 798.056 1.01005 3.99028
+ 12 1.5 793.114 1.03073 3.96557
+ 13 2.5 782.812 1.04569 3.91406
+ 14 3.5 775.69 1.05498 3.87845
+ 15 4.5 778.094 1.05965 3.89047
+ 16 5.5 778.856 1.06002 3.89428
+ 17 6.5 780.51 1.05621 3.90255
+ 18 7.5 780.518 1.04782 3.90259
+ 19 8.5 789.698 1.03348 3.94849
+ 20 9.5 792.29 1.01261 3.96145
diff --git a/examples/USER/meso/mdpd/in.mdpd b/examples/USER/meso/mdpd/in.mdpd
new file mode 100644
index 0000000000..201b4a340e
--- /dev/null
+++ b/examples/USER/meso/mdpd/in.mdpd
@@ -0,0 +1,52 @@
+########################################################################
+#### 3D droplet oscilation using many-body DPD simulation ###
+#### ###
+#### Created : Zhen Li (zhen_li@brown.edu) ###
+#### Division of Applied Mathematics, Brown University. ###
+#### ###
+#### mDPD parameters follow the choice of the publication: ###
+#### Z. Li et al. "Three dimensional flow structures in a moving ###
+#### droplet on substrate: a dissipative particle dynamics study" ###
+#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.3 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style mdpd
+
+region mdpd block -25 25 -10 10 -10 10 units box
+create_box 1 mdpd
+
+lattice fcc 6
+region film block -20 20 -7.5 7.5 -2.0 2.0 units box
+create_atoms 1 region film
+
+pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598
+pair_coeff 1 1 mdpd/rhosum 0.75
+pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75
+mass 1 1.0
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 38497 loop local dist gaussian
+
+fix mvv all mvv/dpd
+
+#dump mydump all atom 100 atom.lammpstrj
+
+#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 &
+# view 90 90 box no 0 size 600 200
+#dump_modify jpg pad 4
+
+#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 &
+# view 90 90 box no 0 size 600 200
+#dump_modify avi pad 4
+
+timestep 0.01
+run 4000
diff --git a/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1 b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1
new file mode 100644
index 0000000000..c3c14da559
--- /dev/null
+++ b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.1
@@ -0,0 +1,147 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+#### 3D droplet oscilation using many-body DPD simulation ###
+#### ###
+#### Created : Zhen Li (zhen_li@brown.edu) ###
+#### Division of Applied Mathematics, Brown University. ###
+#### ###
+#### mDPD parameters follow the choice of the publication: ###
+#### Z. Li et al. "Three dimensional flow structures in a moving ###
+#### droplet on substrate: a dissipative particle dynamics study" ###
+#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.3 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style mdpd
+
+region mdpd block -25 25 -10 10 -10 10 units box
+create_box 1 mdpd
+Created orthogonal box = (-25 -10 -10) to (25 10 10)
+ 1 by 1 by 1 MPI processor grid
+
+lattice fcc 6
+Lattice spacing in x,y,z = 0.87358 0.87358 0.87358
+region film block -20 20 -7.5 7.5 -2.0 2.0 units box
+create_atoms 1 region film
+Created 14333 atoms
+
+pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598
+pair_coeff 1 1 mdpd/rhosum 0.75
+pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75
+mass 1 1.0
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 38497 loop local dist gaussian
+
+fix mvv all mvv/dpd
+
+dump mydump all atom 100 atom.lammpstrj
+
+#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200
+#dump_modify jpg pad 4
+
+#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200
+#dump_modify avi pad 4
+
+timestep 0.01
+run 4000
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.3
+ ghost atom cutoff = 1.3
+ binsize = 0.65, bins = 77 31 31
+ 2 neighbor lists, perpetual/occasional/extra = 2 0 0
+ (1) pair mdpd/rhosum, perpetual
+ attributes: full, newton on
+ pair build: full/bin/atomonly
+ stencil: full/bin/3d
+ bin: standard
+ (2) pair mdpd, perpetual, half/full from (1)
+ attributes: half, newton on
+ pair build: halffull/newton
+ stencil: none
+ bin: none
+Per MPI rank memory allocation (min/avg/max) = 9.931 | 9.931 | 9.931 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 -13.346542 0 -11.846647 -6.8495478
+ 100 1.0321029 -7.2846779 0 -5.7366316 -0.77640205
+ 200 1.042287 -6.9534532 0 -5.3901317 -0.27750815
+ 300 1.0583027 -6.8483105 0 -5.2609672 -0.30347708
+ 400 1.0493719 -6.8648608 0 -5.2909127 -0.15312495
+ 500 1.0723786 -6.8341085 0 -5.2256528 0.017227511
+ 600 1.0545695 -6.8152957 0 -5.2335517 -0.024362439
+ 700 1.0507193 -6.8076033 0 -5.2316344 -0.07101536
+ 800 1.0531856 -6.9378568 0 -5.3581886 -0.053943939
+ 900 1.0442995 -6.8501126 0 -5.2837726 -0.13347942
+ 1000 1.0335049 -6.8883554 0 -5.3382062 -0.18420426
+ 1100 1.0287276 -6.8298226 0 -5.2868389 -0.12081558
+ 1200 1.0322527 -6.9462828 0 -5.3980117 -0.18047625
+ 1300 1.0599443 -6.9449975 0 -5.355192 -0.011763589
+ 1400 1.0560932 -6.845479 0 -5.2614498 0.032130055
+ 1500 1.0432786 -6.9035877 0 -5.338779 -0.10268662
+ 1600 1.064183 -6.9116836 0 -5.3155205 -0.060722129
+ 1700 1.0586249 -6.8768278 0 -5.2890013 0.037005566
+ 1800 1.0576064 -7.0060193 0 -5.4197204 -0.036211254
+ 1900 1.0595141 -6.838741 0 -5.2495807 -0.12395681
+ 2000 1.0650509 -6.897976 0 -5.3005111 0.003594807
+ 2100 1.0768273 -6.8874245 0 -5.2722962 0.033283489
+ 2200 1.0511606 -6.9823162 0 -5.4056854 0.015008427
+ 2300 1.0461138 -6.8820601 0 -5.3129988 0.064646933
+ 2400 1.0485369 -6.9437148 0 -5.3710191 -0.16534939
+ 2500 1.0507221 -6.9394786 0 -5.3635054 -0.098289859
+ 2600 1.0518352 -6.8947578 0 -5.3171152 -0.011666785
+ 2700 1.0402369 -6.9273377 0 -5.3670913 0.035267073
+ 2800 1.0426109 -6.912024 0 -5.3482168 0.049597305
+ 2900 1.0358928 -6.9574778 0 -5.4037471 -0.063216561
+ 3000 1.0351023 -6.9844192 0 -5.4318742 -0.10323465
+ 3100 1.0255005 -6.9382486 0 -5.4001052 -0.073954735
+ 3200 1.0150616 -6.9843183 0 -5.4618321 -0.095136405
+ 3300 1.0118112 -6.9522082 0 -5.4345973 -0.12686179
+ 3400 1.0071522 -6.970158 0 -5.4595351 -0.012487475
+ 3500 1.0041758 -6.9773019 0 -5.4711433 -0.098027653
+ 3600 1.0189298 -6.9393039 0 -5.4110158 0.061631719
+ 3700 1.012442 -6.9341423 0 -5.4155852 0.10442772
+ 3800 1.0021246 -6.9594374 0 -5.4563553 -0.081535223
+ 3900 1.0165002 -6.9045321 0 -5.3798882 -0.0088283303
+ 4000 1.0077099 -6.9145511 0 -5.4030918 0.048349691
+Loop time of 135.409 on 1 procs for 4000 steps with 14333 atoms
+
+Performance: 25522.736 tau/day, 29.540 timesteps/s
+99.9% CPU use with 1 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 93.074 | 93.074 | 93.074 | 0.0 | 68.74
+Neigh | 40.192 | 40.192 | 40.192 | 0.0 | 29.68
+Comm | 0.19625 | 0.19625 | 0.19625 | 0.0 | 0.14
+Output | 0.41756 | 0.41756 | 0.41756 | 0.0 | 0.31
+Modify | 1.0706 | 1.0706 | 1.0706 | 0.0 | 0.79
+Other | | 0.4581 | | | 0.34
+
+Nlocal: 14333 ave 14333 max 14333 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 11 ave 11 max 11 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 401803 ave 401803 max 401803 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+FullNghs: 803606 ave 803606 max 803606 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 803606
+Ave neighs/atom = 56.0668
+Neighbor list builds = 1050
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:02:15
diff --git a/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4 b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4
new file mode 100644
index 0000000000..ec3d8fbddc
--- /dev/null
+++ b/examples/USER/meso/mdpd/log.16Aug17.mdpd.g++.4
@@ -0,0 +1,147 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+#### 3D droplet oscilation using many-body DPD simulation ###
+#### ###
+#### Created : Zhen Li (zhen_li@brown.edu) ###
+#### Division of Applied Mathematics, Brown University. ###
+#### ###
+#### mDPD parameters follow the choice of the publication: ###
+#### Z. Li et al. "Three dimensional flow structures in a moving ###
+#### droplet on substrate: a dissipative particle dynamics study" ###
+#### Physics of Fluids, 2013, 25: 072103. DOI: 10.1063/1.4812366 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.3 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style mdpd
+
+region mdpd block -25 25 -10 10 -10 10 units box
+create_box 1 mdpd
+Created orthogonal box = (-25 -10 -10) to (25 10 10)
+ 4 by 1 by 1 MPI processor grid
+
+lattice fcc 6
+Lattice spacing in x,y,z = 0.87358 0.87358 0.87358
+region film block -20 20 -7.5 7.5 -2.0 2.0 units box
+create_atoms 1 region film
+Created 14333 atoms
+
+pair_style hybrid/overlay mdpd/rhosum mdpd 1.0 1.0 9872598
+pair_coeff 1 1 mdpd/rhosum 0.75
+pair_coeff 1 1 mdpd -40 25 18.0 1.0 0.75
+mass 1 1.0
+
+compute mythermo all temp
+thermo 100
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 38497 loop local dist gaussian
+
+fix mvv all mvv/dpd
+
+dump mydump all atom 100 atom.lammpstrj
+
+#dump jpg all image 200 image.*.jpg type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200
+#dump_modify jpg pad 4
+
+#dump avi all movie 200 movie.avi type type zoom 5 adiam 0.5 # view 90 90 box no 0 size 600 200
+#dump_modify avi pad 4
+
+timestep 0.01
+run 4000
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.3
+ ghost atom cutoff = 1.3
+ binsize = 0.65, bins = 77 31 31
+ 2 neighbor lists, perpetual/occasional/extra = 2 0 0
+ (1) pair mdpd/rhosum, perpetual
+ attributes: full, newton on
+ pair build: full/bin/atomonly
+ stencil: full/bin/3d
+ bin: standard
+ (2) pair mdpd, perpetual, half/full from (1)
+ attributes: half, newton on
+ pair build: halffull/newton
+ stencil: none
+ bin: none
+Per MPI rank memory allocation (min/avg/max) = 6.265 | 6.655 | 7.045 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 -13.346542 0 -11.846647 -6.9757225
+ 100 1.0406108 -7.2500697 0 -5.6892624 -0.80306477
+ 200 1.0535506 -6.9452928 0 -5.3650772 -0.39911584
+ 300 1.0644295 -6.8599907 0 -5.2634577 -0.2997968
+ 400 1.0780123 -6.9471342 0 -5.3302286 -0.06274869
+ 500 1.0672153 -6.8269984 0 -5.2262872 0.021251762
+ 600 1.0634304 -6.8366569 0 -5.2416226 -0.021863333
+ 700 1.0544807 -6.8272074 0 -5.2455967 -0.0064688066
+ 800 1.0556172 -6.8859788 0 -5.3026634 0.023983333
+ 900 1.0436201 -6.9246523 0 -5.3593313 -0.12409618
+ 1000 1.0617016 -6.8632331 0 -5.2707919 -0.1145505
+ 1100 1.0323831 -6.951554 0 -5.4030874 -0.030031884
+ 1200 1.0407785 -6.931048 0 -5.3699892 -0.018362136
+ 1300 1.0380953 -6.8785296 0 -5.3214953 -0.099308737
+ 1400 1.0418898 -6.8998 0 -5.3370743 -0.14199421
+ 1500 1.0487254 -6.9671212 0 -5.3941429 -0.12132644
+ 1600 1.0561042 -6.8948881 0 -5.3108424 -0.09627292
+ 1700 1.0524479 -6.9531441 0 -5.3745823 -0.11959782
+ 1800 1.0541197 -6.9219819 0 -5.3409126 0.032964029
+ 1900 1.0531221 -6.8805815 0 -5.3010085 0.030124685
+ 2000 1.0531819 -6.8612868 0 -5.2816242 -0.076876781
+ 2100 1.0757791 -6.919875 0 -5.3063189 -0.04060439
+ 2200 1.069423 -6.9005754 0 -5.2965527 0.015347467
+ 2300 1.0403109 -6.9015402 0 -5.3411827 0.0034687897
+ 2400 1.0547448 -6.9325539 0 -5.3505471 -0.021202325
+ 2500 1.0404195 -6.8494675 0 -5.2889472 0.086947847
+ 2600 1.0499828 -6.9861392 0 -5.4112749 -0.018079308
+ 2700 1.0294278 -6.8525151 0 -5.3084811 0.16911472
+ 2800 1.0220652 -6.8993978 0 -5.366407 0.064820531
+ 2900 1.0347904 -6.9322703 0 -5.3801929 -0.11384964
+ 3000 1.0391372 -6.9519088 0 -5.3933117 0.003050577
+ 3100 1.0335828 -7.0090074 0 -5.4587413 -0.17366664
+ 3200 1.0211896 -6.9421289 0 -5.4104513 0.025299853
+ 3300 1.0019232 -6.9426488 0 -5.4398688 -0.098334724
+ 3400 1.0203541 -6.9310981 0 -5.4006737 -0.0015544982
+ 3500 1.0076794 -6.9519932 0 -5.4405796 -0.056956902
+ 3600 1.0086525 -6.9620979 0 -5.4492247 0.020014884
+ 3700 1.0046112 -7.0011625 0 -5.4943508 -0.083936527
+ 3800 1.0096867 -6.9470382 0 -5.4326138 -0.089521759
+ 3900 1.0074482 -6.9959414 0 -5.4848745 -0.11873698
+ 4000 1.01222 -6.9535694 0 -5.4353454 0.042191466
+Loop time of 63.0327 on 4 procs for 4000 steps with 14333 atoms
+
+Performance: 54828.695 tau/day, 63.459 timesteps/s
+98.8% CPU use with 4 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 16.591 | 29.795 | 42.814 | 236.6 | 47.27
+Neigh | 2.0347 | 10.239 | 18.555 | 255.6 | 16.24
+Comm | 0.70099 | 6.0601 | 11.386 | 207.4 | 9.61
+Output | 0.20713 | 0.40902 | 0.61087 | 31.5 | 0.65
+Modify | 0.058089 | 0.27033 | 0.4851 | 40.7 | 0.43
+Other | | 16.26 | | | 25.79
+
+Nlocal: 3583.25 ave 7207 max 0 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+Nghost: 1055.75 ave 2131 max 0 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+Neighs: 100549 ave 202192 max 0 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+FullNghs: 201098 ave 404372 max 0 min
+Histogram: 2 0 0 0 0 0 0 0 0 2
+
+Total # of neighbors = 804390
+Ave neighs/atom = 56.1215
+Neighbor list builds = 1049
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:01:03
diff --git a/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1 b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1
new file mode 100644
index 0000000000..a872600504
--- /dev/null
+++ b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.1
@@ -0,0 +1,24 @@
+# Chunk-averaged data for fix stat and group c_cc2
+# Timestep Number-of-chunks Total-count
+# Chunk Coord1 Ncount c_cc1 c_cc2
+100 20 16000
+ 1 -9.5 797.17 0.986661 1.0077
+ 2 -8.5 802.61 0.967974 1.02003
+ 3 -7.5 795.46 0.957045 1.02873
+ 4 -6.5 806.46 0.951271 1.03428
+ 5 -5.5 802.34 0.94898 1.03692
+ 6 -4.5 799.84 0.949378 1.03673
+ 7 -3.5 798.4 0.952505 1.03374
+ 8 -2.5 800.36 0.959322 1.02778
+ 9 -1.5 797.65 0.971516 1.01867
+ 10 -0.5 808.88 0.990644 1.00626
+ 11 0.5 786.29 1.00924 0.993828
+ 12 1.5 807.16 1.02831 0.981436
+ 13 2.5 797.54 1.04071 0.972184
+ 14 3.5 799.67 1.04749 0.966258
+ 15 4.5 799.61 1.05063 0.963256
+ 16 5.5 806.11 1.05105 0.963052
+ 17 6.5 803.67 1.04877 0.965688
+ 18 7.5 797.39 1.04305 0.971187
+ 19 8.5 801.85 1.03208 0.97993
+ 20 9.5 791.54 1.01351 0.992209
diff --git a/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4 b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4
new file mode 100644
index 0000000000..de34ef26c3
--- /dev/null
+++ b/examples/USER/meso/tdpd/cc.profile.16Aug17.tdpd.g++.4
@@ -0,0 +1,24 @@
+# Chunk-averaged data for fix stat and group c_cc2
+# Timestep Number-of-chunks Total-count
+# Chunk Coord1 Ncount c_cc1 c_cc2
+100 20 16000
+ 1 -9.5 806.92 0.986675 1.00766
+ 2 -8.5 798.01 0.96792 1.02003
+ 3 -7.5 805.43 0.956909 1.02883
+ 4 -6.5 800.54 0.951207 1.03432
+ 5 -5.5 794.14 0.948967 1.03691
+ 6 -4.5 799.75 0.949379 1.03672
+ 7 -3.5 799.65 0.952492 1.03374
+ 8 -2.5 799.94 0.959331 1.02778
+ 9 -1.5 800.96 0.971664 1.01861
+ 10 -0.5 803.97 0.99074 1.00622
+ 11 0.5 800.66 1.00949 0.993673
+ 12 1.5 779.22 1.02824 0.981461
+ 13 2.5 809.13 1.04056 0.972274
+ 14 3.5 805.23 1.04747 0.966272
+ 15 4.5 795.95 1.05061 0.96327
+ 16 5.5 796.4 1.05105 0.963035
+ 17 6.5 806.1 1.04883 0.965621
+ 18 7.5 806.41 1.04305 0.971224
+ 19 8.5 792.2 1.03211 0.979955
+ 20 9.5 799.39 1.01362 0.992156
diff --git a/examples/USER/meso/tdpd/in.tdpd b/examples/USER/meso/tdpd/in.tdpd
new file mode 100644
index 0000000000..748a4f5077
--- /dev/null
+++ b/examples/USER/meso/tdpd/in.tdpd
@@ -0,0 +1,54 @@
+########################################################################
+### Pure diffusion with a reaction source term analog of a periodic ###
+### Poiseuille flow problem using transport DPD (tDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### tDPD system setup follows Fig.1 in the publication: ###
+### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ###
+### "Transport dissipative particle dynamics model for mesoscopic ###
+### advection-diffusion-reaction problems. J. Chem. Phys., ###
+### 2015, 143: 014101. DOI: 10.1063/1.4923254 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style tdpd 2
+
+region tdpd block -10 10 -10 10 -5 5 units box
+create_box 1 tdpd
+create_atoms 1 random 16000 276438 NULL
+mass 1 1.0
+set atom * cc 1 1.0
+set atom * cc 2 1.0
+
+pair_style tdpd 1.0 1.58 9872598
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0
+
+compute mythermo all temp
+thermo 50
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/tdpd 0.5
+fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01
+fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01
+
+timestep 0.01
+run 500
+reset_timestep 0
+
+compute cc1 all tdpd/cc/atom 1
+compute cc2 all tdpd/cc/atom 2
+compute bin all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile
+
+run 100
diff --git a/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1 b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1
new file mode 100644
index 0000000000..21b618148c
--- /dev/null
+++ b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.1
@@ -0,0 +1,146 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+### Pure diffusion with a reaction source term analog of a periodic ###
+### Poiseuille flow problem using transport DPD (tDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### tDPD system setup follows Fig.1 in the publication: ###
+### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ###
+### "Transport dissipative particle dynamics model for mesoscopic ###
+### advection-diffusion-reaction problems. J. Chem. Phys., ###
+### 2015, 143: 014101. DOI: 10.1063/1.4923254 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style tdpd 2
+
+region tdpd block -10 10 -10 10 -5 5 units box
+create_box 1 tdpd
+Created orthogonal box = (-10 -10 -5) to (10 10 5)
+ 1 by 1 by 1 MPI processor grid
+create_atoms 1 random 16000 276438 NULL
+Created 16000 atoms
+mass 1 1.0
+set atom * cc 1 1.0
+ 16000 settings made for cc index 1
+set atom * cc 2 1.0
+ 16000 settings made for cc index 2
+
+pair_style tdpd 1.0 1.58 9872598
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0
+
+compute mythermo all temp
+thermo 50
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/tdpd 0.5
+fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01
+fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01
+
+timestep 0.01
+run 500
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.78
+ ghost atom cutoff = 1.78
+ binsize = 0.89, bins = 23 23 12
+ 1 neighbor lists, perpetual/occasional/extra = 1 0 0
+ (1) pair tdpd, perpetual
+ attributes: half, newton on
+ pair build: half/bin/atomonly/newton
+ stencil: half/bin/3d/newton
+ bin: standard
+Per MPI rank memory allocation (min/avg/max) = 11.3 | 11.3 | 11.3 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 48.948932 0 50.448838 202.19166
+ 50 0.99837766 43.949877 0 45.447349 195.80936
+ 100 0.99846831 43.756995 0 45.254604 198.22348
+ 150 1.0026903 43.72408 0 45.228021 196.61676
+ 200 1.0063144 43.722388 0 45.231765 194.17954
+ 250 1.0032304 43.721864 0 45.226615 197.85829
+ 300 0.9932656 43.703526 0 45.193331 196.57406
+ 350 1.0002916 43.720498 0 45.220841 193.55346
+ 400 0.99475486 43.722965 0 45.215004 196.81546
+ 450 1.0011803 43.712447 0 45.214124 200.46118
+ 500 1.0009006 43.708984 0 45.210241 197.38953
+Loop time of 96.0326 on 1 procs for 500 steps with 16000 atoms
+
+Performance: 4498.474 tau/day, 5.207 timesteps/s
+99.9% CPU use with 1 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 90.083 | 90.083 | 90.083 | 0.0 | 93.80
+Neigh | 5.049 | 5.049 | 5.049 | 0.0 | 5.26
+Comm | 0.34141 | 0.34141 | 0.34141 | 0.0 | 0.36
+Output | 0.00092816 | 0.00092816 | 0.00092816 | 0.0 | 0.00
+Modify | 0.45991 | 0.45991 | 0.45991 | 0.0 | 0.48
+Other | | 0.09865 | | | 0.10
+
+Nlocal: 16000 ave 16000 max 16000 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 14091 ave 14091 max 14091 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 749379 ave 749379 max 749379 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 749379
+Ave neighs/atom = 46.8362
+Neighbor list builds = 183
+Dangerous builds = 0
+reset_timestep 0
+
+compute cc1 all tdpd/cc/atom 1
+compute cc2 all tdpd/cc/atom 2
+compute bin all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile
+
+run 100
+Per MPI rank memory allocation (min/avg/max) = 11.8 | 11.8 | 11.8 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1.0009006 43.708984 0 45.210241 199.3205
+ 50 1.0007276 43.704844 0 45.205842 197.77053
+ 100 1.0039032 43.714201 0 45.219961 197.31118
+Loop time of 19.0326 on 1 procs for 100 steps with 16000 atoms
+
+Performance: 4539.577 tau/day, 5.254 timesteps/s
+99.9% CPU use with 1 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 17.842 | 17.842 | 17.842 | 0.0 | 93.74
+Neigh | 0.98674 | 0.98674 | 0.98674 | 0.0 | 5.18
+Comm | 0.066013 | 0.066013 | 0.066013 | 0.0 | 0.35
+Output | 0.00016284 | 0.00016284 | 0.00016284 | 0.0 | 0.00
+Modify | 0.11795 | 0.11795 | 0.11795 | 0.0 | 0.62
+Other | | 0.02012 | | | 0.11
+
+Nlocal: 16000 ave 16000 max 16000 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Nghost: 14126 ave 14126 max 14126 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+Neighs: 748927 ave 748927 max 748927 min
+Histogram: 1 0 0 0 0 0 0 0 0 0
+
+Total # of neighbors = 748927
+Ave neighs/atom = 46.8079
+Neighbor list builds = 37
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:01:55
diff --git a/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4 b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4
new file mode 100644
index 0000000000..6cd99168f4
--- /dev/null
+++ b/examples/USER/meso/tdpd/log.16Aug17.tdpd.g++.4
@@ -0,0 +1,146 @@
+LAMMPS (11 Aug 2017)
+########################################################################
+### Pure diffusion with a reaction source term analog of a periodic ###
+### Poiseuille flow problem using transport DPD (tDPD) simulation ###
+### ###
+### Created : Zhen Li (zhen_li@brown.edu) ###
+### Division of Applied Mathematics, Brown University. ###
+### ###
+### tDPD system setup follows Fig.1 in the publication: ###
+### Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. ###
+### "Transport dissipative particle dynamics model for mesoscopic ###
+### advection-diffusion-reaction problems. J. Chem. Phys., ###
+### 2015, 143: 014101. DOI: 10.1063/1.4923254 ###
+########################################################################
+units lj
+dimension 3
+boundary p p p
+neighbor 0.2 bin
+neigh_modify every 1 delay 0 check yes
+
+atom_style tdpd 2
+
+region tdpd block -10 10 -10 10 -5 5 units box
+create_box 1 tdpd
+Created orthogonal box = (-10 -10 -5) to (10 10 5)
+ 2 by 2 by 1 MPI processor grid
+create_atoms 1 random 16000 276438 NULL
+Created 16000 atoms
+mass 1 1.0
+set atom * cc 1 1.0
+ 16000 settings made for cc index 1
+set atom * cc 2 1.0
+ 16000 settings made for cc index 2
+
+pair_style tdpd 1.0 1.58 9872598
+pair_coeff 1 1 18.75 4.5 0.41 1.58 1.58 1.0 1.0E-5 2.0 3.0 1.0E-5 2.0
+
+compute mythermo all temp
+thermo 50
+thermo_modify temp mythermo
+thermo_modify flush yes
+
+velocity all create 1.0 432982 loop local dist gaussian
+
+fix mvv all mvv/tdpd 0.5
+fix upper1 all tdpd/source 1 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 0.01
+fix lower1 all tdpd/source 1 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 -0.01
+fix upper2 all tdpd/source 2 cuboid 0.0 5.0 0.0 20.0 10.0 10.0 -0.01
+fix lower2 all tdpd/source 2 cuboid 0.0 -5.0 0.0 20.0 10.0 10.0 0.01
+
+timestep 0.01
+run 500
+Neighbor list info ...
+ update every 1 steps, delay 0 steps, check yes
+ max neighbors/atom: 2000, page size: 100000
+ master list distance cutoff = 1.78
+ ghost atom cutoff = 1.78
+ binsize = 0.89, bins = 23 23 12
+ 1 neighbor lists, perpetual/occasional/extra = 1 0 0
+ (1) pair tdpd, perpetual
+ attributes: half, newton on
+ pair build: half/bin/atomonly/newton
+ stencil: half/bin/3d/newton
+ bin: standard
+Per MPI rank memory allocation (min/avg/max) = 4.814 | 4.823 | 4.829 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1 48.948932 0 50.448838 199.65978
+ 50 1.0153476 43.948796 0 45.471722 198.3346
+ 100 1.0064284 43.754875 0 45.264424 197.5308
+ 150 0.99609985 43.726751 0 45.220807 197.50623
+ 200 1.0016604 43.720283 0 45.22268 197.81129
+ 250 1.0054979 43.718568 0 45.22672 195.79405
+ 300 0.9997618 43.716617 0 45.216166 197.84788
+ 350 0.99170101 43.72093 0 45.208389 196.07711
+ 400 1.0043692 43.71648 0 45.22294 199.55247
+ 450 1.0086263 43.709988 0 45.222833 198.20516
+ 500 1.0029076 43.717879 0 45.222146 197.26281
+Loop time of 24.5533 on 4 procs for 500 steps with 16000 atoms
+
+Performance: 17594.412 tau/day, 20.364 timesteps/s
+99.9% CPU use with 4 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 22.236 | 22.418 | 22.736 | 4.0 | 91.30
+Neigh | 1.2759 | 1.2883 | 1.3077 | 1.1 | 5.25
+Comm | 0.35749 | 0.69526 | 0.88462 | 24.1 | 2.83
+Output | 0.00043321 | 0.00050318 | 0.00070691 | 0.0 | 0.00
+Modify | 0.11555 | 0.11648 | 0.11888 | 0.4 | 0.47
+Other | | 0.03473 | | | 0.14
+
+Nlocal: 4000 ave 4012 max 3982 min
+Histogram: 1 0 0 0 0 1 0 0 0 2
+Nghost: 5986.25 ave 6016 max 5956 min
+Histogram: 1 0 0 0 1 0 1 0 0 1
+Neighs: 187309 ave 188264 max 186087 min
+Histogram: 1 0 0 0 1 0 0 1 0 1
+
+Total # of neighbors = 749235
+Ave neighs/atom = 46.8272
+Neighbor list builds = 180
+Dangerous builds = 0
+reset_timestep 0
+
+compute cc1 all tdpd/cc/atom 1
+compute cc2 all tdpd/cc/atom 2
+compute bin all chunk/atom bin/1d y 0.0 1.0
+fix stat all ave/chunk 1 100 100 bin c_cc1 c_cc2 norm sample file cc.profile
+
+run 100
+Per MPI rank memory allocation (min/avg/max) = 5.065 | 5.074 | 5.082 Mbytes
+Step Temp E_pair E_mol TotEng Press
+ 0 1.0029076 43.717879 0 45.222146 198.45789
+ 50 1.0077982 43.713264 0 45.224867 196.56183
+ 100 1.0036823 43.708022 0 45.213451 196.00815
+Loop time of 4.79577 on 4 procs for 100 steps with 16000 atoms
+
+Performance: 18015.870 tau/day, 20.852 timesteps/s
+99.9% CPU use with 4 MPI tasks x no OpenMP threads
+
+MPI task timing breakdown:
+Section | min time | avg time | max time |%varavg| %total
+---------------------------------------------------------------
+Pair | 4.3481 | 4.39 | 4.4398 | 1.7 | 91.54
+Neigh | 0.25477 | 0.25675 | 0.25963 | 0.4 | 5.35
+Comm | 0.059327 | 0.11194 | 0.15608 | 11.0 | 2.33
+Output | 0.00011206 | 0.00011748 | 0.00011992 | 0.0 | 0.00
+Modify | 0.030417 | 0.030622 | 0.030739 | 0.1 | 0.64
+Other | | 0.006301 | | | 0.13
+
+Nlocal: 4000 ave 4010 max 3987 min
+Histogram: 1 0 0 0 0 1 1 0 0 1
+Nghost: 5985.25 ave 6025 max 5959 min
+Histogram: 2 0 0 0 0 1 0 0 0 1
+Neighs: 187304 ave 188092 max 186449 min
+Histogram: 1 0 0 0 0 2 0 0 0 1
+
+Total # of neighbors = 749216
+Ave neighs/atom = 46.826
+Neighbor list builds = 38
+Dangerous builds = 0
+
+Please see the log.cite file for references relevant to this simulation
+
+Total wall time: 0:00:29
diff --git a/src/.gitignore b/src/.gitignore
index 80166e260e..ff589bc701 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -60,6 +60,35 @@
/intel_preprocess.h
/intel_simd.h
+/atom_vec_edpd.cpp
+/atom_vec_edpd.h
+/atom_vec_mdpd.cpp
+/atom_vec_mdpd.h
+/atom_vec_tdpd.cpp
+/atom_vec_tdpd.h
+/compute_edpd_temp_atom.cpp
+/compute_edpd_temp_atom.h
+/compute_tdpd_cc_atom.cpp
+/compute_tdpd_cc_atom.h
+/fix_edpd_source.cpp
+/fix_edpd_source.h
+/fix_mvv_dpd.cpp
+/fix_mvv_dpd.h
+/fix_mvv_edpd.cpp
+/fix_mvv_edpd.h
+/fix_mvv_tdpd.cpp
+/fix_mvv_tdpd.h
+/fix_tdpd_source.cpp
+/fix_tdpd_source.h
+/pair_edpd.cpp
+/pair_edpd.h
+/pair_mdpd.cpp
+/pair_mdpd.h
+/pair_mdpd_rhosum.cpp
+/pair_mdpd_rhosum.h
+/pair_tdpd.cpp
+/pair_tdpd.h
+
/compute_sna_atom.cpp
/compute_sna_atom.h
/compute_snad_atom.cpp
diff --git a/src/Makefile b/src/Makefile
index 3b67d2284f..91d65a11c5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -59,7 +59,8 @@ PACKAGE = asphere body class2 colloid compress coreshell dipole gpu \
PACKUSER = user-atc user-awpmd user-cgdna user-cgsdk user-colvars \
user-diffraction user-dpd user-drude user-eff user-fep user-h5md \
- user-intel user-lb user-manifold user-meamc user-mgpt user-misc user-molfile \
+ user-intel user-lb user-manifold user-meamc user-meso \
+ user-mgpt user-misc user-molfile \
user-netcdf user-omp user-phonon user-qmmm user-qtb \
user-quip user-reaxc user-smd user-smtbq user-sph user-tally \
user-vtk
diff --git a/src/USER-MESO/README b/src/USER-MESO/README
new file mode 100644
index 0000000000..0119fdb9f8
--- /dev/null
+++ b/src/USER-MESO/README
@@ -0,0 +1,50 @@
+This package implements three extensions of the dissipative particle
+dynamics (DPD) method, i.e., energy-conserving DPD (eDPD) that can
+model non-isothermal processes, many-body DPD (mDPD) for simulating
+vapor-liquid coexistence, and transport DPD (tDPD) for modeling
+advection-diffuion-reaction systems. The equations of motion of these
+DPD extensions are integrated through the modified velocity-Verlet
+(MVV) algorithm.
+
+Currently, the package has the following features:
+
+* Three new atom styles (eDPD, mDPD, tDPD) for tracking the particles
+ with internal temperature, local mass density, and chemical
+ concentration.
+
+* Three set commands (edpd/temp, edpd/cv, cc) for setting internal
+ temperature (edpd/temp) and heat capacity (edpd/cv) for eDPD
+ particles and for setting chemical concentration (cc) for tDPD
+ particles.
+
+* Two compute commands (edpd/temp/atom, tdpd/cc/atom) for accessing
+ the internal temperature of eDPD particles and the chemical
+ concentration of tDPD particles.
+
+* Three fix commands (mvv/dpd, mvv/edpd, mvv/tdpd) for integrating the
+ shochastic ODEs using the modified velocity-Verlet (MVV) algorithm.
+
+* Two fix commands (edpd/source, tdpd/source) for adding additional
+ heat source/sink or chemical concentration source/sink to eDPD and
+ tDPD particles.
+
+* One pair style (edpd) for modeling a eDPD fluid.
+
+* Two pair styles (mdpd/rhosum, mdpd) for modeling a mDPD fluid.
+
+* One pair style (tdpd) for modeling a tDPD fluid.
+
+See the doc pages for "atom style edpd", "atom style mdpd", "atom
+style tdpd", "set edpd/temp", "set edpd/cv", "set tdpd/cc", "compute
+edpd/temp/atom", "compute tdpd/cc/atom", "fix mvv/dpd", "fix
+mvv/edpd", "fix mvv/tdpd", "fix edpd/source", "fix tdpd/source", "pair
+edpd", "pair mdpd/rhosum", "pair mdpd", "pair tdpd" commands to get
+started. At the bottom of the doc pages are many links to additional
+documentation contained in the doc/USER/meso directory.
+
+There are example scripts for using this package in
+examples/USER/meso.
+
+The person who created this package is Zhen Li (zhen_li at brown.edu)
+at Division of Applied Mathematics, Brown University, USA. Contact him
+directly if you have questions.
diff --git a/src/USER-MESO/atom_vec_edpd.cpp b/src/USER-MESO/atom_vec_edpd.cpp
new file mode 100644
index 0000000000..385e8fd426
--- /dev/null
+++ b/src/USER-MESO/atom_vec_edpd.cpp
@@ -0,0 +1,844 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+#include
+#include
+#include "atom_vec_edpd.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "modify.h"
+#include "fix.h"
+#include "update.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecEDPD::AtomVecEDPD(LAMMPS *lmp) : AtomVec(lmp)
+{
+ if(strcmp(update->unit_style,"lj") != 0)
+ error->all(FLERR,"Atom style edpd requires lj units");
+
+ molecular = 0;
+ mass_type = 1;
+ forceclearflag = 1;
+
+ comm_x_only = comm_f_only = 0;
+ comm->ghost_velocity = 1;
+
+ size_forward = 3 + 5; // edpd_temp + vest[4]
+ size_reverse = 3 + 1; // edpd_flux
+ size_border = 6 + 6; // edpd_temp + edpd_cv + vest[4]
+ size_velocity = 3;
+ size_data_atom = 5 + 2; // we read id + type + edpd_temp + edpd_cv + xyz[3]
+ size_data_vel = 4;
+ xcol_data = 5;
+
+ atom->edpd_flag = 1;
+ atom->vest_flag = 1;
+}
+
+/* ----------------------------------------------------------------------
+ grow atom arrays
+ n = 0 grows arrays by a chunk
+ n > 0 allocates arrays to size n
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::grow(int n)
+{
+ if (n == 0) grow_nmax();
+ else nmax = n;
+ atom->nmax = nmax;
+ if (nmax < 0 || nmax > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ tag = memory->grow(atom->tag,nmax,"atom:tag");
+ type = memory->grow(atom->type,nmax,"atom:type");
+ mask = memory->grow(atom->mask,nmax,"atom:mask");
+ image = memory->grow(atom->image,nmax,"atom:image");
+ x = memory->grow(atom->x,nmax,3,"atom:x");
+ v = memory->grow(atom->v,nmax,3,"atom:v");
+ f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
+ edpd_cv= memory->grow(atom->edpd_cv, nmax, "atom:edpd_cv");
+ edpd_temp = memory->grow(atom->edpd_temp, nmax, "atom:edpd_temp");
+ edpd_flux = memory->grow(atom->edpd_flux, nmax*comm->nthreads,"atom:edpd_flux");
+ vest = memory->grow(atom->vest, nmax, 4, "atom:vest");
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ----------------------------------------------------------------------
+ reset local array ptrs
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::grow_reset()
+{
+ tag = atom->tag; type = atom->type;
+ mask = atom->mask; image = atom->image;
+ x = atom->x; v = atom->v; f = atom->f;
+ edpd_cv = atom->cv; edpd_temp = atom->edpd_temp; edpd_flux = atom->edpd_flux;
+ vest = atom->vest;
+}
+
+/* ----------------------------------------------------------------------
+ copy atom I info to atom J
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::copy(int i, int j, int delflag)
+{
+ tag[j] = tag[i];
+ type[j] = type[i];
+ mask[j] = mask[i];
+ image[j] = image[i];
+ x[j][0] = x[i][0];
+ x[j][1] = x[i][1];
+ x[j][2] = x[i][2];
+ v[j][0] = v[i][0];
+ v[j][1] = v[i][1];
+ v[j][2] = v[i][2];
+
+ edpd_temp[j] = edpd_temp[i];
+ edpd_flux[j] = edpd_flux[i];
+ edpd_cv[j] = edpd_cv[i];
+ vest[j][0] = vest[i][0];
+ vest[j][1] = vest[i][1];
+ vest[j][2] = vest[i][2];
+ vest[j][3] = vest[i][3];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag);
+}
+
+
+void AtomVecEDPD::force_clear(int n, size_t nbytes)
+{
+ memset(&edpd_flux[n],0,nbytes);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_comm(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = edpd_temp[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_comm_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = edpd_temp[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = edpd_temp[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ buf[m++] = edpd_temp[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEDPD::unpack_comm(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ edpd_temp[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ vest[i][3] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEDPD::unpack_comm_vel(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ edpd_temp[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ vest[i][3] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_reverse(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = f[i][0];
+ buf[m++] = f[i][1];
+ buf[m++] = f[i][2];
+ buf[m++] = edpd_flux[i];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEDPD::unpack_reverse(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ f[j][0] += buf[m++];
+ f[j][1] += buf[m++];
+ f[j][2] += buf[m++];
+ edpd_flux[j] += buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_border(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = edpd_cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = edpd_cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_border_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = edpd_cv[j];
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = edpd_cv[j];
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = edpd_temp[j];
+ buf[m++] = edpd_cv[j];
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ buf[m++] = vest[j][0] + dvx;
+ buf[m++] = vest[j][1] + dvy;
+ buf[m++] = vest[j][2] + dvz;
+ buf[m++] = vest[j][3];
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ buf[m++] = vest[j][3];
+ }
+ }
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEDPD::unpack_border(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax) grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ edpd_temp[i] = buf[m++];
+ edpd_cv[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ vest[i][3] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEDPD::unpack_border_vel(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax) grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ edpd_temp[i] = buf[m++];
+ edpd_cv[i] = buf[m++];
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ vest[i][3] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ----------------------------------------------------------------------
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+------------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_exchange(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ buf[m++] = edpd_temp[i];
+ buf[m++] = edpd_cv[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+ buf[m++] = vest[i][3];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEDPD::unpack_exchange(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ edpd_temp[nlocal] = buf[m++];
+ edpd_cv[nlocal] = buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+ vest[nlocal][3] = buf[m++];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->
+ unpack_exchange(nlocal,&buf[m]);
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+------------------------------------------------------------------------- */
+
+int AtomVecEDPD::size_restart()
+{
+ int i;
+
+ int nlocal = atom->nlocal;
+ int n = (11 + 6) * nlocal; // 11 + edpd_temp + edpd_cv + vest[4]
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ for (i = 0; i < nlocal; i++)
+ n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+ return n;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom I's data for restart file including extra quantities
+ xyz must be 1st 3 values, so that read_restart can test on them
+ molecular types may be negative, but write as positive
+------------------------------------------------------------------------- */
+
+int AtomVecEDPD::pack_restart(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = edpd_temp[i];
+ buf[m++] = edpd_cv[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+ buf[m++] = vest[i][3];
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ unpack data for one atom from restart file including extra quantities
+------------------------------------------------------------------------- */
+
+int AtomVecEDPD::unpack_restart(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
+ }
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+
+ edpd_temp[nlocal] = buf[m++];
+ edpd_cv[nlocal]= buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+ vest[nlocal][3] = buf[m++];
+
+ double **extra = atom->extra;
+ if (atom->nextra_store) {
+ int size = static_cast (buf[0]) - m;
+ for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+ }
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ create one atom of itype at coord
+ set other values to defaults
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::create_atom(int itype, double *coord)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = 0;
+ type[nlocal] = itype;
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+ mask[nlocal] = 1;
+ image[nlocal] = ((imageint) IMGMAX << IMG2BITS) |
+ ((imageint) IMGMAX << IMGBITS) | IMGMAX;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ edpd_temp[nlocal] = 1.0;
+ edpd_flux[nlocal] = 0.0;
+ edpd_cv[nlocal]= 1.0E5;
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+ vest[nlocal][3] = edpd_temp[nlocal];
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Atoms section of data file
+ initialize other atom quantities
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::data_atom(double *coord, imageint imagetmp, char **values)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = ATOTAGINT(values[0]);
+ type[nlocal] = atoi(values[1]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ edpd_temp[nlocal] = atof(values[2]);
+ edpd_cv[nlocal] = atof(values[3]);
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+ vest[nlocal][3] = edpd_temp[nlocal];
+ edpd_flux[nlocal] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom info for data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::pack_data(double **buf)
+{
+ int nlocal = atom->nlocal;
+ for (int i = 0; i < nlocal; i++) {
+ buf[i][0] = ubuf(tag[i]).d;
+ buf[i][1] = ubuf(type[i]).d;
+ buf[i][2] = edpd_temp[i];
+ buf[i][3] = edpd_cv[i];
+ buf[i][4] = x[i][0];
+ buf[i][5] = x[i][1];
+ buf[i][6] = x[i][2];
+ buf[i][7] = ubuf((image[i] & IMGMASK) - IMGMAX).d;
+ buf[i][8] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d;
+ buf[i][9] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ write atom info to data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecEDPD::write_data(FILE *fp, int n, double **buf)
+{
+ for (int i = 0; i < n; i++)
+ fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+ (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+ buf[i][2],buf[i][3],buf[i][4],buf[i][5],buf[i][6],
+ (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i);
+}
+
+/* ----------------------------------------------------------------------
+ return # of bytes of allocated memory
+------------------------------------------------------------------------- */
+
+bigint AtomVecEDPD::memory_usage()
+{
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
+ if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
+ if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
+ if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
+ if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
+ if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
+ if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
+ if (atom->memcheck("edpd_temp")) bytes += memory->usage(edpd_temp,nmax);
+ if (atom->memcheck("edpd_flux")) bytes += memory->usage(edpd_flux,nmax*comm->nthreads);
+ if (atom->memcheck("edpd_cv")) bytes += memory->usage(edpd_cv,nmax);
+ if (atom->memcheck("vest")) bytes += memory->usage(vest,nmax,4);
+
+ return bytes;
+}
diff --git a/src/USER-MESO/atom_vec_edpd.h b/src/USER-MESO/atom_vec_edpd.h
new file mode 100644
index 0000000000..36a4cae97b
--- /dev/null
+++ b/src/USER-MESO/atom_vec_edpd.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef ATOM_CLASS
+
+AtomStyle(edpd,AtomVecEDPD)
+
+#else
+
+#ifndef LMP_ATOM_VEC_EDPD_H
+#define LMP_ATOM_VEC_EDPD_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecEDPD : public AtomVec {
+ public:
+ AtomVecEDPD(class LAMMPS *);
+ virtual ~AtomVecEDPD() {}
+ void grow(int);
+ void grow_reset();
+ void copy(int, int, int);
+ void force_clear(int, size_t);
+ virtual int pack_comm(int, int *, double *, int, int *);
+ virtual int pack_comm_vel(int, int *, double *, int, int *);
+ virtual void unpack_comm(int, int, double *);
+ virtual void unpack_comm_vel(int, int, double *);
+ int pack_reverse(int, int, double *);
+ void unpack_reverse(int, int *, double *);
+ virtual int pack_border(int, int *, double *, int, int *);
+ virtual int pack_border_vel(int, int *, double *, int, int *);
+ virtual void unpack_border(int, int, double *);
+ virtual void unpack_border_vel(int, int, double *);
+ virtual int pack_exchange(int, double *);
+ virtual int unpack_exchange(double *);
+ int size_restart();
+ int pack_restart(int, double *);
+ int unpack_restart(double *);
+ void create_atom(int, double *);
+ void data_atom(double *, imageint, char **);
+ void pack_data(double **);
+ void write_data(FILE *, int, double **);
+ bigint memory_usage();
+
+ protected:
+ tagint *tag;
+ int *type,*mask;
+ imageint *image;
+ double **x,**v,**f;
+ double **vest; // store intermediate velocity for using mvv integrator
+ double *edpd_temp,*edpd_flux,*edpd_cv; // temperature, heat flux, and heat capacity
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/atom_vec_mdpd.cpp b/src/USER-MESO/atom_vec_mdpd.cpp
new file mode 100644
index 0000000000..0a4d302c36
--- /dev/null
+++ b/src/USER-MESO/atom_vec_mdpd.cpp
@@ -0,0 +1,951 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+ ------------------------------------------------------------------------- */
+
+#include
+#include
+#include "atom_vec_mdpd.h"
+#include "atom.h"
+#include "comm.h"
+#include "domain.h"
+#include "modify.h"
+#include "fix.h"
+#include "update.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecMDPD::AtomVecMDPD(LAMMPS *lmp) : AtomVec(lmp)
+{
+ if(strcmp(update->unit_style,"lj") != 0)
+ error->all(FLERR,"Atom style mdpd requires lj units");
+
+ molecular = 0;
+ mass_type = 1;
+ forceclearflag = 1;
+
+ comm_x_only = comm_f_only = 0;
+ comm->ghost_velocity = 1;
+
+ size_forward = 3 + 4; // 3 + rho + vest[3], that means we may only communicate 4 in hybrid
+ size_reverse = 3 + 1; // 3 + drho
+ size_border = 6 + 4; // 6 + rho + vest[3]
+ size_velocity = 3;
+ size_data_atom = 5;
+ size_data_vel = 4;
+ xcol_data = 3;
+
+ atom->rho_flag = 1;
+ atom->vest_flag = 1;
+}
+
+/* ----------------------------------------------------------------------
+ grow atom arrays
+ n = 0 grows arrays by a chunk
+ n > 0 allocates arrays to size n
+ ------------------------------------------------------------------------- */
+
+void AtomVecMDPD::grow(int n)
+{
+ if (n == 0) grow_nmax();
+ else nmax = n;
+ atom->nmax = nmax;
+ if (nmax < 0 || nmax > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ tag = memory->grow(atom->tag, nmax, "atom:tag");
+ type = memory->grow(atom->type, nmax, "atom:type");
+ mask = memory->grow(atom->mask, nmax, "atom:mask");
+ image = memory->grow(atom->image, nmax, "atom:image");
+ x = memory->grow(atom->x, nmax, 3, "atom:x");
+ v = memory->grow(atom->v, nmax, 3, "atom:v");
+ f = memory->grow(atom->f, nmax*comm->nthreads, 3, "atom:f");
+
+ rho = memory->grow(atom->rho, nmax, "atom:rho");
+ drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho");
+ vest = memory->grow(atom->vest, nmax, 3, "atom:vest");
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ----------------------------------------------------------------------
+ reset local array ptrs
+ ------------------------------------------------------------------------- */
+
+void AtomVecMDPD::grow_reset() {
+ tag = atom->tag;
+ type = atom->type;
+ mask = atom->mask;
+ image = atom->image;
+ x = atom->x;
+ v = atom->v;
+ f = atom->f;
+ rho = atom->rho;
+ drho = atom->drho;
+ vest = atom->vest;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::copy(int i, int j, int delflag) {
+ //printf("in AtomVecMDPD::copy\n");
+ tag[j] = tag[i];
+ type[j] = type[i];
+ mask[j] = mask[i];
+ image[j] = image[i];
+ x[j][0] = x[i][0];
+ x[j][1] = x[i][1];
+ x[j][2] = x[i][2];
+ v[j][0] = v[i][0];
+ v[j][1] = v[i][1];
+ v[j][2] = v[i][2];
+
+ rho[j] = rho[i];
+ drho[j] = drho[i];
+ vest[j][0] = vest[i][0];
+ vest[j][1] = vest[i][1];
+ vest[j][2] = vest[i][2];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->copy_arrays(i, j,delflag);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::force_clear(int n, size_t nbytes)
+{
+ memset(&drho[n],0,nbytes);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_comm_hybrid(int n, int *list, double *buf) {
+ //printf("in AtomVecMDPD::pack_comm_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::unpack_comm_hybrid(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_comm_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_border_hybrid(int n, int *list, double *buf) {
+ //printf("in AtomVecMDPD::pack_border_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::unpack_border_hybrid(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_border_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_reverse_hybrid(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::pack_reverse_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = drho[i];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::unpack_reverse_hybrid(int n, int *list, double *buf) {
+ //printf("in AtomVecMDPD::unpack_reverse_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ drho[j] += buf[m++];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_comm(int n, int *list, double *buf, int pbc_flag,
+ int *pbc) {
+ //printf("in AtomVecMDPD::pack_comm\n");
+ int i, j, m;
+ double dx, dy, dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0] * domain->xprd;
+ dy = pbc[1] * domain->yprd;
+ dz = pbc[2] * domain->zprd;
+ } else {
+ dx = pbc[0] * domain->xprd + pbc[5] * domain->xy + pbc[4] * domain->xz;
+ dy = pbc[1] * domain->yprd + pbc[3] * domain->yz;
+ dz = pbc[2] * domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_comm_vel(int n, int *list, double *buf, int pbc_flag,
+ int *pbc) {
+ //printf("in AtomVecMDPD::pack_comm_vel\n");
+ int i, j, m;
+ double dx, dy, dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0] * domain->xprd;
+ dy = pbc[1] * domain->yprd;
+ dz = pbc[2] * domain->zprd;
+ } else {
+ dx = pbc[0] * domain->xprd + pbc[5] * domain->xy + pbc[4] * domain->xz;
+ dy = pbc[1] * domain->yprd + pbc[3] * domain->yz;
+ dz = pbc[2] * domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::unpack_comm(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_comm\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::unpack_comm_vel(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_comm_vel\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_reverse(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::pack_reverse\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = f[i][0];
+ buf[m++] = f[i][1];
+ buf[m++] = f[i][2];
+ buf[m++] = drho[i];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::unpack_reverse(int n, int *list, double *buf) {
+ //printf("in AtomVecMDPD::unpack_reverse\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ f[j][0] += buf[m++];
+ f[j][1] += buf[m++];
+ f[j][2] += buf[m++];
+ drho[j] += buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_border(int n, int *list, double *buf, int pbc_flag,
+ int *pbc) {
+ //printf("in AtomVecMDPD::pack_border\n");
+ int i, j, m;
+ double dx, dy, dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0] * domain->xprd;
+ dy = pbc[1] * domain->yprd;
+ dz = pbc[2] * domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_border_vel(int n, int *list, double *buf, int pbc_flag,
+ int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0] * domain->xprd;
+ dy = pbc[1] * domain->yprd;
+ dz = pbc[2] * domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ dvx = pbc[0] * h_rate[0] + pbc[5] * h_rate[5] + pbc[4] * h_rate[4];
+ dvy = pbc[1] * h_rate[1] + pbc[3] * h_rate[3];
+ dvz = pbc[2] * h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0] + dvx;
+ buf[m++] = vest[j][1] + dvy;
+ buf[m++] = vest[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ buf[m++] = rho[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::unpack_border(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_border\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax)
+ grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecMDPD::unpack_border_vel(int n, int first, double *buf) {
+ //printf("in AtomVecMDPD::unpack_border_vel\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax)
+ grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ rho[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ----------------------------------------------------------------------
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+ ------------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_exchange(int i, double *buf) {
+ //printf("in AtomVecMDPD::pack_exchange\n");
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ buf[m++] = rho[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i, &buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecMDPD::unpack_exchange(double *buf) {
+ //printf("in AtomVecMDPD::unpack_exchange\n");
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax)
+ grow(0);
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ rho[nlocal] = buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]-> unpack_exchange(nlocal,
+ &buf[m]);
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+ ------------------------------------------------------------------------- */
+
+int AtomVecMDPD::size_restart() {
+ int i;
+
+ int nlocal = atom->nlocal;
+ int n = 15 * nlocal; // 11 + rho + vest[3]
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ for (i = 0; i < nlocal; i++)
+ n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+ return n;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom I's data for restart file including extra quantities
+ xyz must be 1st 3 values, so that read_restart can test on them
+ molecular types may be negative, but write as positive
+ ------------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_restart(int i, double *buf) {
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = rho[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i, &buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ unpack data for one atom from restart file including extra quantities
+ ------------------------------------------------------------------------- */
+
+int AtomVecMDPD::unpack_restart(double *buf) {
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(atom->extra, nmax, atom->nextra_store, "atom:extra");
+ }
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ rho[nlocal] = buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+
+ double **extra = atom->extra;
+ if (atom->nextra_store) {
+ int size = static_cast (buf[0]) - m;
+ for (int i = 0; i < size; i++)
+ extra[nlocal][i] = buf[m++];
+ }
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ create one atom of itype at coord
+ set other values to defaults
+ ------------------------------------------------------------------------- */
+
+void AtomVecMDPD::create_atom(int itype, double *coord) {
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax)
+ grow(0);
+
+ tag[nlocal] = 0;
+ type[nlocal] = itype;
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+ mask[nlocal] = 1;
+ image[nlocal] = ((imageint) IMGMAX << IMG2BITS) |
+ ((imageint) IMGMAX << IMGBITS) | IMGMAX;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+ rho[nlocal] = 0.0;
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+ drho[nlocal] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Atoms section of data file
+ initialize other atom quantities
+ ------------------------------------------------------------------------- */
+
+void AtomVecMDPD::data_atom(double *coord, imageint imagetmp, char **values) {
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = ATOTAGINT(values[0]);
+ type[nlocal] = atoi(values[1]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+
+ rho[nlocal] = 0.0;
+ drho[nlocal] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack hybrid quantities from one line in Atoms section of data file
+ initialize other atom quantities for this sub-style
+ ------------------------------------------------------------------------- */
+
+int AtomVecMDPD::data_atom_hybrid(int nlocal, char **values)
+{
+ rho[nlocal] = atof(values[0]);
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom info for data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecMDPD::pack_data(double **buf)
+{
+ int nlocal = atom->nlocal;
+ for (int i = 0; i < nlocal; i++) {
+ buf[i][0] = ubuf(tag[i]).d;
+ buf[i][1] = ubuf(type[i]).d;
+ buf[i][2] = rho[i];
+ buf[i][3] = x[i][0];
+ buf[i][4] = x[i][1];
+ buf[i][5] = x[i][2];
+ buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d;
+ buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d;
+ buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ pack hybrid atom info for data file
+------------------------------------------------------------------------- */
+
+int AtomVecMDPD::pack_data_hybrid(int i, double *buf)
+{
+ buf[0] = rho[i];
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ write atom info to data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecMDPD::write_data(FILE *fp, int n, double **buf)
+{
+ for (int i = 0; i < n; i++)
+ fprintf(fp,TAGINT_FORMAT
+ " %d %-1.16e %-1.16e %-1.16e %-1.16e "
+ "%d %d %d\n",
+ (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+ buf[i][2],buf[i][3],buf[i][4],buf[i][5],
+ (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
+ (int) ubuf(buf[i][8]).i);
+}
+
+/* ----------------------------------------------------------------------
+ write hybrid atom info to data file
+------------------------------------------------------------------------- */
+
+int AtomVecMDPD::write_data_hybrid(FILE *fp, double *buf)
+{
+ fprintf(fp," %-1.16e",buf[0]);
+ return 3;
+}
+
+/* ----------------------------------------------------------------------
+ assign an index to named atom property and return index
+ return -1 if name is unknown to this atom style
+------------------------------------------------------------------------- */
+
+int AtomVecMDPD::property_atom(char *name)
+{
+ if (strcmp(name,"rho") == 0) return 0;
+ if (strcmp(name,"drho") == 0) return 1;
+ return -1;
+}
+
+/* ----------------------------------------------------------------------
+ pack per-atom data into buf for ComputePropertyAtom
+ index maps to data specific to this atom style
+------------------------------------------------------------------------- */
+
+void AtomVecMDPD::pack_property_atom(int index, double *buf,
+ int nvalues, int groupbit)
+{
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ int n = 0;
+
+ if (index == 0) {
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) buf[n] = rho[i];
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+ } else if (index == 1) {
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) buf[n] = drho[i];
+ else buf[n] = 0.0;
+ n += nvalues;
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ return # of bytes of allocated memory
+ ------------------------------------------------------------------------- */
+
+bigint AtomVecMDPD::memory_usage() {
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag")) bytes += memory->usage(tag, nmax);
+ if (atom->memcheck("type")) bytes += memory->usage(type, nmax);
+ if (atom->memcheck("mask")) bytes += memory->usage(mask, nmax);
+ if (atom->memcheck("image")) bytes += memory->usage(image, nmax);
+ if (atom->memcheck("x")) bytes += memory->usage(x, nmax, 3);
+ if (atom->memcheck("v")) bytes += memory->usage(v, nmax, 3);
+ if (atom->memcheck("f")) bytes += memory->usage(f, nmax*comm->nthreads, 3);
+ if (atom->memcheck("rho")) bytes += memory->usage(rho, nmax);
+ if (atom->memcheck("drho")) bytes += memory->usage(drho, nmax*comm->nthreads);
+ if (atom->memcheck("vest")) bytes += memory->usage(vest, nmax, 3);
+
+ return bytes;
+}
diff --git a/src/USER-MESO/atom_vec_mdpd.h b/src/USER-MESO/atom_vec_mdpd.h
new file mode 100644
index 0000000000..9e9ffcdcf2
--- /dev/null
+++ b/src/USER-MESO/atom_vec_mdpd.h
@@ -0,0 +1,79 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef ATOM_CLASS
+
+AtomStyle(mdpd,AtomVecMDPD)
+
+#else
+
+#ifndef LMP_ATOM_VEC_MDPD_H
+#define LMP_ATOM_VEC_MDPD_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecMDPD : public AtomVec {
+ public:
+ AtomVecMDPD(class LAMMPS *);
+ ~AtomVecMDPD() {}
+ void grow(int);
+ void grow_reset();
+ void copy(int, int, int);
+ void force_clear(int, size_t);
+ int pack_comm(int, int *, double *, int, int *);
+ int pack_comm_vel(int, int *, double *, int, int *);
+ void unpack_comm(int, int, double *);
+ void unpack_comm_vel(int, int, double *);
+ int pack_reverse(int, int, double *);
+ void unpack_reverse(int, int *, double *);
+ int pack_comm_hybrid(int, int *, double *);
+ int unpack_comm_hybrid(int, int, double *);
+ int pack_border_hybrid(int, int *, double *);
+ int unpack_border_hybrid(int, int, double *);
+ int pack_reverse_hybrid(int, int, double *);
+ int unpack_reverse_hybrid(int, int *, double *);
+ int pack_border(int, int *, double *, int, int *);
+ int pack_border_vel(int, int *, double *, int, int *);
+ void unpack_border(int, int, double *);
+ void unpack_border_vel(int, int, double *);
+ int pack_exchange(int, double *);
+ int unpack_exchange(double *);
+ int size_restart();
+ int pack_restart(int, double *);
+ int unpack_restart(double *);
+ void create_atom(int, double *);
+ void data_atom(double *, imageint, char **);
+ int data_atom_hybrid(int, char **);
+ void pack_data(double **);
+ int pack_data_hybrid(int, double *);
+ void write_data(FILE *, int, double **);
+ int write_data_hybrid(FILE *, double *);
+ int property_atom(char *);
+ void pack_property_atom(int, double *, int, int);
+ bigint memory_usage();
+
+ private:
+ tagint *tag;
+ int *type,*mask;
+ imageint *image;
+ double **x,**v,**f;
+ double *rho, *drho;
+ double **vest; // estimated velocity during force computation
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/atom_vec_tdpd.cpp b/src/USER-MESO/atom_vec_tdpd.cpp
new file mode 100644
index 0000000000..34f2b1a031
--- /dev/null
+++ b/src/USER-MESO/atom_vec_tdpd.cpp
@@ -0,0 +1,879 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "atom_vec_tdpd.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "domain.h"
+#include "modify.h"
+#include "fix.h"
+#include "update.h"
+#include "memory.h"
+#include "error.h"
+#include "input.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecTDPD::AtomVecTDPD(LAMMPS *lmp) : AtomVec(lmp)
+{
+ if(strcmp(update->unit_style,"lj") != 0)
+ error->all(FLERR,"Atom style edpd requires lj units");
+
+ molecular = 0;
+ mass_type = 1;
+ forceclearflag = 1;
+
+ comm_x_only = comm_f_only = 0;
+ comm->ghost_velocity = 1;
+
+ cc_species = 0; // for now, reset in process_args()
+
+ size_forward = 3 + cc_species + 3; //vest[3]
+ size_reverse = 3 + cc_species;
+ size_border = 6 + cc_species + 3; //vest[3]
+ size_velocity = 3;
+ // for data_atom, we read id + type + xyz[3] + cc[i] where i=1,cc_species
+ size_data_atom = 5 + cc_species;
+ size_data_vel = 4;
+ xcol_data = 3;
+
+ atom->tdpd_flag = 1;
+ atom->vest_flag = 1;
+}
+
+/* ----------------------------------------------------------------------
+ process additional args
+ single arg = number of cc_species
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::process_args(int narg, char **arg)
+{
+ if (narg < 1) error->all(FLERR,"Invalid atom_style tdpd command");
+
+ atom->cc_species = force->inumeric(FLERR,arg[0]);
+ cc_species = atom->cc_species;
+
+ // reset sizes that depend on cc_species
+
+ size_forward = 3 + cc_species + 3;
+ size_reverse = 3 + cc_species;
+ size_border = 6 + cc_species + 3;
+ size_data_atom = 5 + cc_species;
+}
+
+/* ----------------------------------------------------------------------
+ grow atom arrays
+ n = 0 grows arrays by a chunk
+ n > 0 allocates arrays to size n
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::grow(int n)
+{
+ if (n == 0) grow_nmax();
+ else nmax = n;
+ atom->nmax = nmax;
+ if (nmax < 0 || nmax > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ tag = memory->grow(atom->tag,nmax,"atom:tag");
+ type = memory->grow(atom->type,nmax,"atom:type");
+ mask = memory->grow(atom->mask,nmax,"atom:mask");
+ image = memory->grow(atom->image,nmax,"atom:image");
+ x = memory->grow(atom->x,nmax,3,"atom:x");
+ v = memory->grow(atom->v,nmax,3,"atom:v");
+ f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
+ cc = memory->grow(atom->cc,nmax*comm->nthreads,cc_species,"atom:cc");
+ cc_flux = memory->grow(atom->cc_flux,nmax*comm->nthreads,cc_species,
+ "atom:cc_flux");
+ vest = memory->grow(atom->vest, nmax, 3, "atom:vest");
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ----------------------------------------------------------------------
+ reset local array ptrs
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::grow_reset()
+{
+ tag = atom->tag; type = atom->type;
+ mask = atom->mask; image = atom->image;
+ x = atom->x; v = atom->v; f = atom->f;
+ cc = atom->cc; cc_flux = atom->cc_flux;
+ vest = atom->vest;
+}
+
+/* ----------------------------------------------------------------------
+ copy atom I info to atom J
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::copy(int i, int j, int delflag)
+{
+ tag[j] = tag[i];
+ type[j] = type[i];
+ mask[j] = mask[i];
+ image[j] = image[i];
+ x[j][0] = x[i][0];
+ x[j][1] = x[i][1];
+ x[j][2] = x[i][2];
+ v[j][0] = v[i][0];
+ v[j][1] = v[i][1];
+ v[j][2] = v[i][2];
+
+ for(int k = 0; k < cc_species; k++)
+ cc[j][k] = cc[i][k];
+
+ vest[j][0] = vest[i][0];
+ vest[j][1] = vest[i][1];
+ vest[j][2] = vest[i][2];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag);
+}
+
+
+void AtomVecTDPD::force_clear(int n, size_t nbytes)
+{
+ memset(&cc_flux[n][0],0,cc_species*nbytes);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_comm(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,k,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+
+ for(k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+
+ for(k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_comm_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,k,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+
+ for(k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+ dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+ dz = pbc[2]*domain->zprd;
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+
+ for(k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ for(k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTDPD::unpack_comm(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] = buf[m++];
+
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTDPD::unpack_comm_vel(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] = buf[m++];
+
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_reverse(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = f[i][0];
+ buf[m++] = f[i][1];
+ buf[m++] = f[i][2];
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc_flux[i][k];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTDPD::unpack_reverse(int n, int *list, double *buf)
+{
+ int i,j,m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ f[j][0] += buf[m++];
+ f[j][1] += buf[m++];
+ f[j][2] += buf[m++];
+ for(int k = 0; k < cc_species; k++)
+ cc_flux[j][k] += buf[m++];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_border(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_border_vel(int n, int *list, double *buf,
+ int pbc_flag, int *pbc)
+{
+ int i,j,m;
+ double dx,dy,dz,dvx,dvy,dvz;
+
+ m = 0;
+ if (pbc_flag == 0) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0];
+ buf[m++] = x[j][1];
+ buf[m++] = x[j][2];
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ if (domain->triclinic == 0) {
+ dx = pbc[0]*domain->xprd;
+ dy = pbc[1]*domain->yprd;
+ dz = pbc[2]*domain->zprd;
+ } else {
+ dx = pbc[0];
+ dy = pbc[1];
+ dz = pbc[2];
+ }
+ if (!deform_vremap) {
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ } else {
+ dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
+ dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
+ dvz = pbc[2]*h_rate[2];
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ buf[m++] = ubuf(tag[j]).d;
+ buf[m++] = ubuf(type[j]).d;
+ buf[m++] = ubuf(mask[j]).d;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ buf[m++] = v[j][0];
+ buf[m++] = v[j][1];
+ buf[m++] = v[j][2];
+ }
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[j][k];
+
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]);
+
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTDPD::unpack_border(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax) grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] = buf[m++];
+
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecTDPD::unpack_border_vel(int n, int first, double *buf)
+{
+ int i,m,last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ if (i == nmax) grow(0);
+ x[i][0] = buf[m++];
+ x[i][1] = buf[m++];
+ x[i][2] = buf[m++];
+ tag[i] = (tagint) ubuf(buf[m++]).i;
+ type[i] = (int) ubuf(buf[m++]).i;
+ mask[i] = (int) ubuf(buf[m++]).i;
+ v[i][0] = buf[m++];
+ v[i][1] = buf[m++];
+ v[i][2] = buf[m++];
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] = buf[m++];
+
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+
+ if (atom->nextra_border)
+ for (int iextra = 0; iextra < atom->nextra_border; iextra++)
+ m += modify->fix[atom->extra_border[iextra]]->
+ unpack_border(n,first,&buf[m]);
+}
+
+/* ----------------------------------------------------------------------
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+------------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_exchange(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[i][k];
+
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecTDPD::unpack_exchange(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ for(int k = 0; k < cc_species; k++)
+ cc[nlocal][k] = buf[m++];
+
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+
+ if (atom->nextra_grow)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ m += modify->fix[atom->extra_grow[iextra]]->
+ unpack_exchange(nlocal,&buf[m]);
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+------------------------------------------------------------------------- */
+
+int AtomVecTDPD::size_restart()
+{
+ int i;
+
+ int nlocal = atom->nlocal;
+ int n = (11 + cc_species + 3) * nlocal; // 11 + cc[i] + vest[3]
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ for (i = 0; i < nlocal; i++)
+ n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+ return n;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom I's data for restart file including extra quantities
+ xyz must be 1st 3 values, so that read_restart can test on them
+ molecular types may be negative, but write as positive
+------------------------------------------------------------------------- */
+
+int AtomVecTDPD::pack_restart(int i, double *buf)
+{
+ int m = 1;
+ buf[m++] = x[i][0];
+ buf[m++] = x[i][1];
+ buf[m++] = x[i][2];
+ buf[m++] = ubuf(tag[i]).d;
+ buf[m++] = ubuf(type[i]).d;
+ buf[m++] = ubuf(mask[i]).d;
+ buf[m++] = ubuf(image[i]).d;
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ for(int k = 0; k < cc_species; k++)
+ buf[m++] = cc[i][k];
+
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[i][2];
+
+ if (atom->nextra_restart)
+ for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+ m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
+ buf[0] = m;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ unpack data for one atom from restart file including extra quantities
+------------------------------------------------------------------------- */
+
+int AtomVecTDPD::unpack_restart(double *buf)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra");
+ }
+
+ int m = 1;
+ x[nlocal][0] = buf[m++];
+ x[nlocal][1] = buf[m++];
+ x[nlocal][2] = buf[m++];
+ tag[nlocal] = (tagint) ubuf(buf[m++]).i;
+ type[nlocal] = (int) ubuf(buf[m++]).i;
+ mask[nlocal] = (int) ubuf(buf[m++]).i;
+ image[nlocal] = (imageint) ubuf(buf[m++]).i;
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ for(int k = 0; k < cc_species; k++)
+ cc[nlocal][k] = buf[m++];
+
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[nlocal][2] = buf[m++];
+
+ double **extra = atom->extra;
+ if (atom->nextra_store) {
+ int size = static_cast (buf[0]) - m;
+ for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+ }
+
+ atom->nlocal++;
+ return m;
+}
+
+/* ----------------------------------------------------------------------
+ create one atom of itype at coord
+ set other values to defaults
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::create_atom(int itype, double *coord)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = 0;
+ type[nlocal] = itype;
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+ mask[nlocal] = 1;
+ image[nlocal] = ((imageint) IMGMAX << IMG2BITS) |
+ ((imageint) IMGMAX << IMGBITS) | IMGMAX;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ for(int k = 0; k < cc_species; k++)
+ cc[nlocal][k] = 0.0;
+
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ unpack one line from Atoms section of data file
+ initialize other atom quantities
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::data_atom(double *coord, imageint imagetmp, char **values)
+{
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) grow(0);
+
+ tag[nlocal] = ATOTAGINT(values[0]);
+ type[nlocal] = atoi(values[1]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ for(int k = 0; k < cc_species; k++)
+ cc[nlocal][k] = atof( values[5+k] );
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+
+ atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+ pack atom info for data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::pack_data(double **buf)
+{
+ int nlocal = atom->nlocal;
+ for (int i = 0; i < nlocal; i++) {
+ buf[i][0] = ubuf(tag[i]).d;
+ buf[i][1] = ubuf(type[i]).d;
+ buf[i][2] = x[i][0];
+ buf[i][3] = x[i][1];
+ buf[i][4] = x[i][2];
+ buf[i][5] = ubuf((image[i] & IMGMASK) - IMGMAX).d;
+ buf[i][6] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d;
+ buf[i][7] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d;
+ for(int k = 0; k < cc_species; k++)
+ buf[i][8+k] = cc[i][k];
+ }
+}
+
+/* ----------------------------------------------------------------------
+ write atom info to data file including 3 image flags
+------------------------------------------------------------------------- */
+
+void AtomVecTDPD::write_data(FILE *fp, int n, double **buf)
+{
+ for (int i = 0; i < n; i++){
+ fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %d %d %d",
+ (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+ buf[i][2],buf[i][3],buf[i][4],
+ (int) ubuf(buf[i][5]).i,(int) ubuf(buf[i][6]).i,
+ (int) ubuf(buf[i][7]).i);
+ for(int k = 0; k < cc_species; k++)
+ fprintf(fp," %-1.16e",buf[i][8+k]);
+ fprintf(fp,"\n");
+ }
+}
+
+/* ----------------------------------------------------------------------
+ return # of bytes of allocated memory
+------------------------------------------------------------------------- */
+
+bigint AtomVecTDPD::memory_usage()
+{
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
+ if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
+ if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
+ if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
+ if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
+ if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
+ if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
+ if (atom->memcheck("cc")) bytes += memory->usage(cc,nmax*comm->nthreads,cc_species);
+ if (atom->memcheck("cc_flux")) bytes += memory->usage(cc_flux,nmax*comm->nthreads,cc_species);
+ if (atom->memcheck("vest")) bytes += memory->usage(vest, nmax);
+
+ return bytes;
+}
diff --git a/src/USER-MESO/atom_vec_tdpd.h b/src/USER-MESO/atom_vec_tdpd.h
new file mode 100644
index 0000000000..86e9ae4bb8
--- /dev/null
+++ b/src/USER-MESO/atom_vec_tdpd.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef ATOM_CLASS
+
+AtomStyle(tdpd,AtomVecTDPD)
+
+#else
+
+#ifndef LMP_ATOM_VEC_TDPD_H
+#define LMP_ATOM_VEC_TDPD_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecTDPD : public AtomVec {
+ public:
+ AtomVecTDPD(class LAMMPS *);
+ virtual ~AtomVecTDPD() {}
+ void process_args(int, char **);
+ void grow(int);
+ void grow_reset();
+ void copy(int, int, int);
+ void force_clear(int, size_t);
+ virtual int pack_comm(int, int *, double *, int, int *);
+ virtual int pack_comm_vel(int, int *, double *, int, int *);
+ virtual void unpack_comm(int, int, double *);
+ virtual void unpack_comm_vel(int, int, double *);
+ int pack_reverse(int, int, double *);
+ void unpack_reverse(int, int *, double *);
+ virtual int pack_border(int, int *, double *, int, int *);
+ virtual int pack_border_vel(int, int *, double *, int, int *);
+ virtual void unpack_border(int, int, double *);
+ virtual void unpack_border_vel(int, int, double *);
+ virtual int pack_exchange(int, double *);
+ virtual int unpack_exchange(double *);
+ int size_restart();
+ int pack_restart(int, double *);
+ int unpack_restart(double *);
+ void create_atom(int, double *);
+ void data_atom(double *, imageint, char **);
+ void pack_data(double **);
+ void write_data(FILE *, int, double **);
+ bigint memory_usage();
+
+ protected:
+ tagint *tag;
+ int *type,*mask;
+ imageint *image;
+ double **x,**v,**f;
+ double **vest; // store intermediate velocity for using mvv integrator
+ double **cc,**cc_flux;
+ int cc_species;
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: Per-processor system is too big
+
+The number of owned atoms plus ghost atoms on a single
+processor must fit in 32-bit integer.
+
+E: Invalid atom type in Atoms section of data file
+
+Atom types must range from 1 to specified # of types.
+
+*/
diff --git a/src/USER-MESO/compute_edpd_temp_atom.cpp b/src/USER-MESO/compute_edpd_temp_atom.cpp
new file mode 100644
index 0000000000..15fdab2a69
--- /dev/null
+++ b/src/USER-MESO/compute_edpd_temp_atom.cpp
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include
+#include "compute_edpd_temp_atom.h"
+#include "atom.h"
+#include "update.h"
+#include "modify.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+ComputeEDPDTempAtom::ComputeEDPDTempAtom(LAMMPS *lmp, int narg, char **arg) :
+ Compute(lmp, narg, arg)
+{
+ if (narg != 3) error->all(FLERR,"Number of arguments for compute edpd/temp/atom command != 3");
+ if (atom->edpd_flag != 1) error->all(FLERR,"compute edpd/temp/atom command requires atom_style with temperature (e.g. edpd)");
+
+ peratom_flag = 1;
+ size_peratom_cols = 0;
+
+ nmax = 0;
+ temp_vector = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+ComputeEDPDTempAtom::~ComputeEDPDTempAtom()
+{
+ memory->sfree(temp_vector);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeEDPDTempAtom::init()
+{
+
+ int count = 0;
+ for (int i = 0; i < modify->ncompute; i++)
+ if (strcmp(modify->compute[i]->style,"temp_vector/atom") == 0) count++;
+ if (count > 1 && comm->me == 0)
+ error->warning(FLERR,"More than one compute temp_vector/atom");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeEDPDTempAtom::compute_peratom()
+{
+ invoked_peratom = update->ntimestep;
+
+ // grow temp_vector array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->sfree(temp_vector);
+ nmax = atom->nmax;
+ temp_vector = (double *) memory->smalloc(nmax*sizeof(double),"temp_vector/atom:temp_vector");
+ vector_atom = temp_vector;
+ }
+
+ double *edpd_temp = atom->edpd_temp;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) {
+ temp_vector[i] = edpd_temp[i];
+ }
+ else {
+ temp_vector[i] = 0.0;
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ memory usage of local atom-based array
+------------------------------------------------------------------------- */
+
+double ComputeEDPDTempAtom::memory_usage()
+{
+ double bytes = nmax * sizeof(double);
+ return bytes;
+}
diff --git a/src/USER-MESO/compute_edpd_temp_atom.h b/src/USER-MESO/compute_edpd_temp_atom.h
new file mode 100644
index 0000000000..4c61b664cc
--- /dev/null
+++ b/src/USER-MESO/compute_edpd_temp_atom.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef COMPUTE_CLASS
+
+ComputeStyle(edpd/temp/atom,ComputeEDPDTempAtom)
+
+#else
+
+#ifndef LMP_COMPUTE_EDPD_TEMP_ATOM_H
+#define LMP_COMPUTE_EDPD_TEMP_ATOM_H
+
+#include "compute.h"
+
+namespace LAMMPS_NS {
+
+class ComputeEDPDTempAtom : public Compute {
+ public:
+ ComputeEDPDTempAtom(class LAMMPS *, int, char **);
+ ~ComputeEDPDTempAtom();
+ void init();
+ void compute_peratom();
+ double memory_usage();
+
+ private:
+ int nmax;
+ double *temp_vector;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/compute_tdpd_cc_atom.cpp b/src/USER-MESO/compute_tdpd_cc_atom.cpp
new file mode 100644
index 0000000000..b33550f5c1
--- /dev/null
+++ b/src/USER-MESO/compute_tdpd_cc_atom.cpp
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include
+#include "compute_tdpd_cc_atom.h"
+#include "atom.h"
+#include "update.h"
+#include "modify.h"
+#include "comm.h"
+#include "force.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+ComputeTDPDCCAtom::ComputeTDPDCCAtom(LAMMPS *lmp, int narg, char **arg) :
+ Compute(lmp, narg, arg)
+{
+ if (narg != 4) error->all(FLERR,"Number of arguments for compute tdpd/cc/atom command != 4");
+ if (atom->tdpd_flag != 1) error->all(FLERR,"compute tdpd/cc/atom command requires atom_style with concentration (e.g. tdpd)");
+
+ index = force->inumeric(FLERR,arg[3]);
+
+ peratom_flag = 1;
+ size_peratom_cols = 0;
+
+ nmax = 0;
+ cc_vector = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+ComputeTDPDCCAtom::~ComputeTDPDCCAtom()
+{
+ memory->sfree(cc_vector);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeTDPDCCAtom::init()
+{
+
+ int count = 0;
+ for (int i = 0; i < modify->ncompute; i++)
+ if (strcmp(modify->compute[i]->style,"cc_vector/atom") == 0) count++;
+ if (count > 1 && comm->me == 0)
+ error->warning(FLERR,"More than one compute cc_vector/atom");
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeTDPDCCAtom::compute_peratom()
+{
+ invoked_peratom = update->ntimestep;
+
+ // grow cc_vector array if necessary
+
+ if (atom->nmax > nmax) {
+ memory->sfree(cc_vector);
+ nmax = atom->nmax;
+ cc_vector = (double *) memory->smalloc(nmax*sizeof(double),"cc_vector/atom:cc_vector");
+ vector_atom = cc_vector;
+ }
+
+ double **cc = atom->cc;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) {
+ cc_vector[i] = cc[i][index-1];
+ }
+ else
+ cc_vector[i] = 0.0;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ memory usage of local atom-based array
+------------------------------------------------------------------------- */
+
+double ComputeTDPDCCAtom::memory_usage()
+{
+ double bytes = nmax * sizeof(double);
+ return bytes;
+}
diff --git a/src/USER-MESO/compute_tdpd_cc_atom.h b/src/USER-MESO/compute_tdpd_cc_atom.h
new file mode 100644
index 0000000000..324cb779a4
--- /dev/null
+++ b/src/USER-MESO/compute_tdpd_cc_atom.h
@@ -0,0 +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.
+------------------------------------------------------------------------- */
+
+#ifdef COMPUTE_CLASS
+
+ComputeStyle(tdpd/cc/atom,ComputeTDPDCCAtom)
+
+#else
+
+#ifndef LMP_COMPUTE_TDPD_CC_ATOM_H
+#define LMP_COMPUTE_TDPD_CC_ATOM_H
+
+#include "compute.h"
+
+namespace LAMMPS_NS {
+
+class ComputeTDPDCCAtom : public Compute {
+ public:
+ ComputeTDPDCCAtom(class LAMMPS *, int, char **);
+ ~ComputeTDPDCCAtom();
+ void init();
+ void compute_peratom();
+ double memory_usage();
+
+ private:
+ int nmax;
+ int index;
+ double *cc_vector;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/fix_edpd_source.cpp b/src/USER-MESO/fix_edpd_source.cpp
new file mode 100644
index 0000000000..3ee7e8e291
--- /dev/null
+++ b/src/USER-MESO/fix_edpd_source.cpp
@@ -0,0 +1,120 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "fix_edpd_source.h"
+#include "atom.h"
+#include "comm.h"
+#include "update.h"
+#include "modify.h"
+#include "domain.h"
+#include "lattice.h"
+#include "input.h"
+#include "variable.h"
+#include "error.h"
+#include "force.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixEDPDSource::FixEDPDSource(LAMMPS *lmp, int narg, char **arg) :
+ Fix(lmp, narg, arg)
+{
+ if (strcmp(style,"edpd/source") != 0 && narg < 4)
+ error->all(FLERR,"Illegal fix edpd/source command");
+
+ int iarg = 3;
+
+ if (strcmp(arg[iarg],"sphere") == 0) option = 0;
+ else if (strcmp(arg[iarg],"cuboid") == 0) option = 1;
+ else error->all(FLERR,"Illegal fix edpd/source command");
+ iarg++;
+
+ if(option == 0){
+ if (narg != 9 ) error->all(FLERR,"Illegal fix edpd/source command (5 args for sphere)");
+ center[0] = force->numeric(FLERR,arg[iarg++]);
+ center[1] = force->numeric(FLERR,arg[iarg++]);
+ center[2] = force->numeric(FLERR,arg[iarg++]);
+ radius = force->numeric(FLERR,arg[iarg++]);
+ value = force->numeric(FLERR,arg[iarg++]);
+ }
+ else if(option == 1){
+ if (narg != 11 ) error->all(FLERR,"Illegal fix edpd/edpd command (7 args for cuboid)");
+ center[0] = force->numeric(FLERR,arg[iarg++]);
+ center[1] = force->numeric(FLERR,arg[iarg++]);
+ center[2] = force->numeric(FLERR,arg[iarg++]);
+ dLx = force->numeric(FLERR,arg[iarg++]);
+ dLy = force->numeric(FLERR,arg[iarg++]);
+ dLz = force->numeric(FLERR,arg[iarg++]);
+ value = force->numeric(FLERR,arg[iarg++]);
+ }
+ else error->all(FLERR,"Illegal fix edpd/source command");
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixEDPDSource::~FixEDPDSource()
+{
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixEDPDSource::setmask()
+{
+ int mask = 0;
+ mask |= POST_FORCE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixEDPDSource::init()
+{
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixEDPDSource::post_force(int vflag)
+{
+ double **x = atom->x;
+ double *edpd_flux = atom->edpd_flux;
+ double *edpd_cv = atom->edpd_cv;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double drx, dry, drz, rsq;
+ double radius_sq = radius*radius*radius;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) {
+ if(option == 0){
+ drx = x[i][0] - center[0];
+ dry = x[i][1] - center[1];
+ drz = x[i][2] - center[2];
+ rsq = drx*drx + dry*dry + drz*drz;
+ if(rsq < radius_sq)
+ edpd_flux[i] += value*edpd_cv[i];
+ }
+ else if(option == 1){
+ drx = x[i][0] - center[0];
+ dry = x[i][1] - center[1];
+ drz = x[i][2] - center[2];
+ if(abs(drx) <= 0.5*dLx && abs(dry) <= 0.5*dLy && abs(drz) <= 0.5*dLz)
+ edpd_flux[i] += value*edpd_cv[i];
+ }
+ }
+ }
+}
diff --git a/src/USER-MESO/fix_edpd_source.h b/src/USER-MESO/fix_edpd_source.h
new file mode 100644
index 0000000000..1ea8610ce9
--- /dev/null
+++ b/src/USER-MESO/fix_edpd_source.h
@@ -0,0 +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.
+------------------------------------------------------------------------- */
+
+#ifdef FIX_CLASS
+
+FixStyle(edpd/source,FixEDPDSource)
+
+#else
+
+#ifndef LMP_FIX_EDPDSOURCE_H
+#define LMP_FIX_EDPDSOURCE_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixEDPDSource : public Fix {
+ public:
+ FixEDPDSource(class LAMMPS *, int, char **);
+ ~FixEDPDSource();
+ int setmask();
+ void init();
+ void post_force(int);
+
+ protected:
+ int option;
+ double center[3], radius, dLx, dLy, dLz;
+ double value;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/fix_mvv_dpd.cpp b/src/USER-MESO/fix_mvv_dpd.cpp
new file mode 100644
index 0000000000..77a67273f6
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_dpd.cpp
@@ -0,0 +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.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ This is a time integrator for position and velocity (x and v) using the
+ modified velocity-Verlet (MVV) algorithm.
+ Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm.
+
+ Contributing author: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "fix_mvv_dpd.h"
+#include "atom.h"
+#include "force.h"
+#include "update.h"
+#include "respa.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixMvvDPD::FixMvvDPD(LAMMPS *lmp, int narg, char **arg) :
+ Fix(lmp, narg, arg)
+{
+ if (strcmp(style,"mvv/dpd") != 0 && narg < 3)
+ error->all(FLERR,"Illegal fix mvv/dpd command");
+
+ verlet = 0.5;
+ if(narg > 3) verlet = force->numeric(FLERR,arg[3]);
+
+ dynamic_group_allow = 1;
+ time_integrate = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixMvvDPD::setmask()
+{
+ int mask = 0;
+ mask |= INITIAL_INTEGRATE;
+ mask |= FINAL_INTEGRATE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvDPD::init()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
+
+/* ----------------------------------------------------------------------
+ allow for both per-type and per-atom mass
+------------------------------------------------------------------------- */
+
+void FixMvvDPD::initial_integrate(int vflag)
+{
+ double dtfm;
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ vest[i][0] = v[i][0] + dtfm * f[i][0];
+ vest[i][1] = v[i][1] + dtfm * f[i][1];
+ vest[i][2] = v[i][2] + dtfm * f[i][2];
+
+ x[i][0] += dtv * vest[i][0];
+ x[i][1] += dtv * vest[i][1];
+ x[i][2] += dtv * vest[i][2];
+ v[i][0] += 2.0 * verlet * dtfm * f[i][0];
+ v[i][1] += 2.0 * verlet * dtfm * f[i][1];
+ v[i][2] += 2.0 * verlet * dtfm * f[i][2];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvDPD::final_integrate()
+{
+ double dtfm;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ v[i][0] = vest[i][0] + dtfm * f[i][0];
+ v[i][1] = vest[i][1] + dtfm * f[i][1];
+ v[i][2] = vest[i][2] + dtfm * f[i][2];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvDPD::reset_dt()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
diff --git a/src/USER-MESO/fix_mvv_dpd.h b/src/USER-MESO/fix_mvv_dpd.h
new file mode 100644
index 0000000000..86cc79485f
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_dpd.h
@@ -0,0 +1,45 @@
+/* -*- 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(mvv/dpd,FixMvvDPD)
+
+#else
+
+#ifndef LMP_FIX_MVV_DPD_H
+#define LMP_FIX_MVV_DPD_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixMvvDPD : public Fix {
+ public:
+ FixMvvDPD(class LAMMPS *, int, char **);
+ virtual ~FixMvvDPD() {}
+ int setmask();
+ virtual void init();
+ virtual void initial_integrate(int);
+ virtual void final_integrate();
+ virtual void reset_dt();
+
+ protected:
+ double dtv, dtf;
+ double verlet;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/fix_mvv_edpd.cpp b/src/USER-MESO/fix_mvv_edpd.cpp
new file mode 100644
index 0000000000..fe801d6d36
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_edpd.cpp
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ This is a time integrator for position, velocity and temperature (x,
+ v and edpd_T) using the modified velocity-Verlet (MVV) algorithm.
+ Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm.
+
+ Contributing author: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+
+ Please cite the related publication:
+ Z. Li, Y.-H. Tang, H. Lei, B. Caswell and G.E. Karniadakis. "Energy-
+ conserving dissipative particle dynamics with temperature-dependent
+ properties". Journal of Computational Physics, 2014, 265: 113-127.
+
+ Z. Li, Y.-H. Tang , X. Li and G.E. Karniadakis. "Mesoscale modeling of
+ phase transition dynamics of thermoresponsive polymers". Chemical
+ Communications, 2015, 51: 11038-11040.
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "fix_mvv_edpd.h"
+#include "atom.h"
+#include "force.h"
+#include "update.h"
+#include "respa.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixMvvEDPD::FixMvvEDPD(LAMMPS *lmp, int narg, char **arg) :
+ Fix(lmp, narg, arg)
+{
+ if (strcmp(style,"mvv/edpd") != 0 && narg < 3)
+ error->all(FLERR,"Illegal fix mvv/edpd command");
+
+ verlet = 0.5;
+ if(narg > 3) verlet = force->numeric(FLERR,arg[3]);
+
+ dynamic_group_allow = 1;
+ time_integrate = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixMvvEDPD::setmask()
+{
+ int mask = 0;
+ mask |= INITIAL_INTEGRATE;
+ mask |= FINAL_INTEGRATE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvEDPD::init()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
+
+/* ----------------------------------------------------------------------
+ allow for both per-type and per-atom mass
+------------------------------------------------------------------------- */
+
+void FixMvvEDPD::initial_integrate(int vflag)
+{
+ double dtfm,dtT;
+ // update v and x and cc of atoms in group
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double *edpd_temp = atom->edpd_temp;
+ double *edpd_flux = atom->edpd_flux;
+ double *edpd_cv = atom->edpd_cv;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ dtT = 0.5 * dtv / edpd_cv[i];
+
+ vest[i][0] = v[i][0] + dtfm * f[i][0];
+ vest[i][1] = v[i][1] + dtfm * f[i][1];
+ vest[i][2] = v[i][2] + dtfm * f[i][2];
+ vest[i][3] = edpd_temp[i] + dtT * edpd_flux[i];
+
+ x[i][0] += dtv * vest[i][0];
+ x[i][1] += dtv * vest[i][1];
+ x[i][2] += dtv * vest[i][2];
+ v[i][0] += 2.0 * verlet * dtfm * f[i][0];
+ v[i][1] += 2.0 * verlet * dtfm * f[i][1];
+ v[i][2] += 2.0 * verlet * dtfm * f[i][2];
+ edpd_temp[i] += 2.0 * verlet * dtT * edpd_flux[i];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvEDPD::final_integrate()
+{
+ double dtfm, dtT;
+
+ // update v and edpd_temp of atoms in group
+
+ double **v = atom->v;
+ double **f = atom->f;
+ double *edpd_temp = atom->edpd_temp;
+ double *edpd_flux = atom->edpd_flux;
+ double *edpd_cv = atom->edpd_cv;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ dtT = 0.5 * dtv / edpd_cv[i];
+
+ v[i][0] = vest[i][0] + dtfm * f[i][0];
+ v[i][1] = vest[i][1] + dtfm * f[i][1];
+ v[i][2] = vest[i][2] + dtfm * f[i][2];
+ edpd_temp[i] = vest[i][3] + dtT * edpd_flux[i];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvEDPD::reset_dt()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
diff --git a/src/USER-MESO/fix_mvv_edpd.h b/src/USER-MESO/fix_mvv_edpd.h
new file mode 100644
index 0000000000..0d9c5f195a
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_edpd.h
@@ -0,0 +1,45 @@
+/* -*- 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(mvv/edpd,FixMvvEDPD)
+
+#else
+
+#ifndef LMP_FIX_MVV_EDPD_H
+#define LMP_FIX_MVV_EDPD_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixMvvEDPD : public Fix {
+ public:
+ FixMvvEDPD(class LAMMPS *, int, char **);
+ virtual ~FixMvvEDPD() {}
+ int setmask();
+ virtual void init();
+ virtual void initial_integrate(int);
+ virtual void final_integrate();
+ virtual void reset_dt();
+
+ protected:
+ double dtv, dtf;
+ double verlet;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/fix_mvv_tdpd.cpp b/src/USER-MESO/fix_mvv_tdpd.cpp
new file mode 100644
index 0000000000..382ce9033a
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_tdpd.cpp
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ This is a time integrator for position, velocity and concentration (x,
+ v and cc) using the modified velocity-Verlet (MVV) algorithm.
+ Setting verlet = 0.5 recovers the standard velocity-Verlet algorithm.
+
+ Contributing author: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+
+ Please cite the related publication:
+ Z. Li, A. Yazdani, A. Tartakovsky and G.E. Karniadakis. "Transport
+ dissipative particle dynamics model for mesoscopic advection-diffusion
+ -reaction problems". The Journal of Chemical Physics, 2015, 143: 014101.
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "fix_mvv_tdpd.h"
+#include "atom.h"
+#include "force.h"
+#include "update.h"
+#include "respa.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixMvvTDPD::FixMvvTDPD(LAMMPS *lmp, int narg, char **arg) :
+ Fix(lmp, narg, arg)
+{
+ if (strcmp(style,"tdpd/verlet") != 0 && narg < 3)
+ error->all(FLERR,"Illegal fix mvv/tdpd command");
+
+ verlet = 0.5;
+ if(narg > 3) verlet = force->numeric(FLERR,arg[3]);
+
+ cc_species = atom->cc_species;
+
+ dynamic_group_allow = 1;
+ time_integrate = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixMvvTDPD::setmask()
+{
+ int mask = 0;
+ mask |= INITIAL_INTEGRATE;
+ mask |= FINAL_INTEGRATE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvTDPD::init()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
+
+/* ----------------------------------------------------------------------
+ allow for both per-type and per-atom mass
+------------------------------------------------------------------------- */
+
+void FixMvvTDPD::initial_integrate(int vflag)
+{
+ double dtfm;
+ // update v and x and cc of atoms in group
+
+ double **x = atom->x;
+ double **v = atom->v;
+ double **f = atom->f;
+ double **cc = atom->cc;
+ double **cc_flux = atom->cc_flux;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ vest[i][0] = v[i][0] + dtfm * f[i][0];
+ vest[i][1] = v[i][1] + dtfm * f[i][1];
+ vest[i][2] = v[i][2] + dtfm * f[i][2];
+
+ x[i][0] += dtv * vest[i][0];
+ x[i][1] += dtv * vest[i][1];
+ x[i][2] += dtv * vest[i][2];
+ v[i][0] += 2.0 * verlet * dtfm * f[i][0];
+ v[i][1] += 2.0 * verlet * dtfm * f[i][1];
+ v[i][2] += 2.0 * verlet * dtfm * f[i][2];
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] += 0.5 * dtv * cc_flux[i][k];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvTDPD::final_integrate()
+{
+ double dtfm;
+
+ // update v of atoms in group
+
+ double **v = atom->v;
+ double **f = atom->f;
+ double **cc = atom->cc;
+ double **cc_flux = atom->cc_flux;
+ double **vest = atom->vest;
+ double *rmass = atom->rmass;
+ double *mass = atom->mass;
+ int *type = atom->type;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+ if (igroup == atom->firstgroup) nlocal = atom->nfirst;
+
+ for (int i = 0; i < nlocal; i++)
+ if (mask[i] & groupbit) {
+ if (rmass) dtfm = dtf / rmass[i];
+ else dtfm = dtf / mass[type[i]];
+
+ v[i][0] = vest[i][0] + dtfm * f[i][0];
+ v[i][1] = vest[i][1] + dtfm * f[i][1];
+ v[i][2] = vest[i][2] + dtfm * f[i][2];
+ for(int k = 0; k < cc_species; k++)
+ cc[i][k] += 0.5 * dtv * cc_flux[i][k];
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixMvvTDPD::reset_dt()
+{
+ dtv = update->dt;
+ dtf = 0.5 * update->dt * force->ftm2v;
+}
diff --git a/src/USER-MESO/fix_mvv_tdpd.h b/src/USER-MESO/fix_mvv_tdpd.h
new file mode 100644
index 0000000000..7adb23af69
--- /dev/null
+++ b/src/USER-MESO/fix_mvv_tdpd.h
@@ -0,0 +1,46 @@
+/* -*- 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(mvv/tdpd,FixMvvTDPD)
+
+#else
+
+#ifndef LMP_FIX_MVV_TDPD_H
+#define LMP_FIX_MVV_TDPD_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixMvvTDPD : public Fix {
+ public:
+ FixMvvTDPD(class LAMMPS *, int, char **);
+ virtual ~FixMvvTDPD() {}
+ int setmask();
+ virtual void init();
+ virtual void initial_integrate(int);
+ virtual void final_integrate();
+ virtual void reset_dt();
+
+ protected:
+ double dtv, dtf;
+ double verlet;
+ int cc_species;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/fix_tdpd_source.cpp b/src/USER-MESO/fix_tdpd_source.cpp
new file mode 100644
index 0000000000..3dfeba4787
--- /dev/null
+++ b/src/USER-MESO/fix_tdpd_source.cpp
@@ -0,0 +1,120 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "fix_tdpd_source.h"
+#include "atom.h"
+#include "comm.h"
+#include "update.h"
+#include "modify.h"
+#include "domain.h"
+#include "lattice.h"
+#include "input.h"
+#include "variable.h"
+#include "error.h"
+#include "force.h"
+
+using namespace LAMMPS_NS;
+using namespace FixConst;
+
+/* ---------------------------------------------------------------------- */
+
+FixTDPDSource::FixTDPDSource(LAMMPS *lmp, int narg, char **arg) :
+ Fix(lmp, narg, arg)
+{
+ if (strcmp(style,"tdpd/source") != 0 && narg < 4)
+ error->all(FLERR,"Illegal fix tdpd/source command");
+
+ int iarg = 3;
+ cc_index = force->inumeric(FLERR,arg[iarg++]);
+
+ if (strcmp(arg[iarg],"sphere") == 0) option = 0;
+ else if (strcmp(arg[iarg],"cuboid") == 0) option = 1;
+ else error->all(FLERR,"Illegal fix tdpd/source command");
+ iarg++;
+
+ if(option == 0){
+ if (narg != 10 ) error->all(FLERR,"Illegal fix tdpd/source command (5 args for sphere)");
+ center[0] = force->numeric(FLERR,arg[iarg++]);
+ center[1] = force->numeric(FLERR,arg[iarg++]);
+ center[2] = force->numeric(FLERR,arg[iarg++]);
+ radius = force->numeric(FLERR,arg[iarg++]);
+ value = force->numeric(FLERR,arg[iarg++]);
+ }
+ else if(option == 1){
+ if (narg != 12 ) error->all(FLERR,"Illegal fix tdpd/edpd command (7 args for cuboid)");
+ center[0] = force->numeric(FLERR,arg[iarg++]);
+ center[1] = force->numeric(FLERR,arg[iarg++]);
+ center[2] = force->numeric(FLERR,arg[iarg++]);
+ dLx = force->numeric(FLERR,arg[iarg++]);
+ dLy = force->numeric(FLERR,arg[iarg++]);
+ dLz = force->numeric(FLERR,arg[iarg++]);
+ value = force->numeric(FLERR,arg[iarg++]);
+ }
+ else error->all(FLERR,"Illegal fix tdpd/source command");
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixTDPDSource::~FixTDPDSource()
+{
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixTDPDSource::setmask()
+{
+ int mask = 0;
+ mask |= POST_FORCE;
+ return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixTDPDSource::init()
+{
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixTDPDSource::post_force(int vflag)
+{
+ double **x = atom->x;
+ double **cc_flux = atom->cc_flux;
+ int *mask = atom->mask;
+ int nlocal = atom->nlocal;
+
+ double drx, dry, drz, rsq;
+ double radius_sq = radius*radius*radius;
+
+ for (int i = 0; i < nlocal; i++) {
+ if (mask[i] & groupbit) {
+ if(option == 0){
+ drx = x[i][0] - center[0];
+ dry = x[i][1] - center[1];
+ drz = x[i][2] - center[2];
+ rsq = drx*drx + dry*dry + drz*drz;
+ if(rsq < radius_sq)
+ cc_flux[i][cc_index-1] += value;
+ }
+ else if(option == 1){
+ drx = x[i][0] - center[0];
+ dry = x[i][1] - center[1];
+ drz = x[i][2] - center[2];
+ if(abs(drx) <= 0.5*dLx && abs(dry) <= 0.5*dLy && abs(drz) <= 0.5*dLz)
+ cc_flux[i][cc_index-1] += value;
+ }
+ }
+ }
+}
diff --git a/src/USER-MESO/fix_tdpd_source.h b/src/USER-MESO/fix_tdpd_source.h
new file mode 100644
index 0000000000..302fe82090
--- /dev/null
+++ b/src/USER-MESO/fix_tdpd_source.h
@@ -0,0 +1,45 @@
+/* -*- 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(tdpd/source,FixTDPDSource)
+
+#else
+
+#ifndef LMP_FIX_TDPDSOURCE_H
+#define LMP_FIX_TDPDSOURCE_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixTDPDSource : public Fix {
+ public:
+ FixTDPDSource(class LAMMPS *, int, char **);
+ ~FixTDPDSource();
+ int setmask();
+ void init();
+ void post_force(int);
+
+ protected:
+ int option;
+ int cc_index;
+ double center[3], radius, dLx, dLy, dLz;
+ double value;
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/pair_edpd.cpp b/src/USER-MESO/pair_edpd.cpp
new file mode 100644
index 0000000000..c1c100db43
--- /dev/null
+++ b/src/USER-MESO/pair_edpd.cpp
@@ -0,0 +1,551 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain 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: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+#include "pair_edpd.h"
+#include "atom.h"
+#include "atom_vec.h"
+#include "comm.h"
+#include "update.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "random_mars.h"
+#include "citeme.h"
+#include "memory.h"
+#include "error.h"
+#include
+#include
+
+using namespace LAMMPS_NS;
+
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#define MAX(A,B) ((A) > (B) ? (A) : (B))
+
+#define EPSILON 1.0e-10
+
+static const char cite_pair_edpd[] =
+ "pair edpd command:\n\n"
+ "@Article{ZLi2014_JCP,\n"
+ " author = {Li, Z. and Tang, Y.-H. and Lei, H. and Caswell, B. and Karniadakis, G.E.},\n"
+ " title = {Energy-conserving dissipative particle dynamics with temperature-dependent properties},\n"
+ " journal = {Journal of Computational Physics},\n"
+ " year = {2014},\n"
+ " volume = {265},\n"
+ " pages = {113--127}\n"
+ "}\n\n"
+ "@Article{ZLi2015_CC,\n"
+ " author = {Li, Z. and Tang, Y.-H. and Li, X. and Karniadakis, G.E.},\n"
+ " title = {Mesoscale modeling of phase transition dynamics of thermoresponsive polymers},\n"
+ " journal = {Chemical Communications},\n"
+ " year = {2015},\n"
+ " volume = {51},\n"
+ " pages = {11038--11040}\n"
+ "}\n\n";
+;
+
+/* ---------------------------------------------------------------------- */
+
+PairEDPD::PairEDPD(LAMMPS *lmp) : Pair(lmp)
+{
+ if (lmp->citeme) lmp->citeme->add(cite_pair_edpd);
+ writedata = 1;
+ random = NULL;
+ randomT = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairEDPD::~PairEDPD()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(cutT);
+
+ memory->destroy(a0);
+ memory->destroy(gamma);
+ memory->destroy(power);
+ memory->destroy(kappa);
+ memory->destroy(powerT);
+ }
+ if (power_flag) memory->destroy(sc);
+ if (kappa_flag) memory->destroy(kc);
+
+ if (random) delete random;
+ if (randomT) delete randomT;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairEDPD::compute(int eflag, int vflag)
+{
+ double evdwl = 0.0;
+ 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 *T = atom->edpd_temp;
+ double *Q = atom->edpd_flux;
+ double *cv = atom->edpd_cv;
+ int *type = atom->type;
+ double *mass = atom->mass;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ int newton_pair = force->newton_pair;
+ double dtinvsqrt = 1.0/sqrt(update->dt);
+ double kboltz = 1.0;
+
+ int inum = list->inum;
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+ for (int ii = 0; ii < inum; ii++) {
+ int i = ilist[ii];
+ double xtmp = x[i][0];
+ double ytmp = x[i][1];
+ double ztmp = x[i][2];
+ double vxtmp = v[i][0];
+ double vytmp = v[i][1];
+ double vztmp = v[i][2];
+ int itype = type[i];
+ int *jlist = firstneigh[i];
+ int jnum = numneigh[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ int j = jlist[jj];
+ double factor_dpd = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ double delx = xtmp - x[j][0];
+ double dely = ytmp - x[j][1];
+ double delz = ztmp - x[j][2];
+ double rsq = delx*delx + dely*dely + delz*delz;
+ int jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ double r = sqrt(rsq);
+ if (r < EPSILON) continue;
+ double rinv = 1.0/r;
+ double delvx = vxtmp - v[j][0];
+ double delvy = vytmp - v[j][1];
+ double delvz = vztmp - v[j][2];
+ double dot = delx*delvx + dely*delvy + delz*delvz;
+ double vijeij = dot*rinv;
+ double randnum = random->gaussian();
+
+ double T_ij=0.5*(T[i]+T[j]);
+ double T_pow[4];
+ T_pow[0] = T_ij - 1.0;
+ T_pow[1] = T_pow[0]*T_pow[0];
+ T_pow[2] = T_pow[0]*T_pow[1];
+ T_pow[3] = T_pow[0]*T_pow[2];
+
+ double power_d = power[itype][jtype];
+ if(power_flag){
+ double factor = 1.0;
+ for(int k = 0; k < 4; k++)
+ factor += sc[itype][jtype][k]*T_pow[k];
+ power_d *= factor;
+ }
+
+ power_d = MAX(0.01,power_d);
+ double wc = 1.0 - r/cut[itype][jtype];
+ wc = MAX(0.0,MIN(1.0,wc));
+ double wr = pow(wc, 0.5*power_d);
+
+ double GammaIJ = gamma[itype][jtype];
+ double SigmaIJ = 4.0*GammaIJ*kboltz*T[i]*T[j]/(T[i]+T[j]);
+ SigmaIJ = sqrt(SigmaIJ);
+
+ double fpair = a0[itype][jtype]*T_ij*wc;
+ fpair -= GammaIJ *wr*wr *dot*rinv;
+ fpair += SigmaIJ * wr *randnum * dtinvsqrt;
+ fpair *= factor_dpd*rinv;
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+
+ // heat transfer
+ double dQc,dQd,dQr;
+ if( r < cutT[itype][jtype]) {
+ double wrT = 1.0 - r/cutT[itype][jtype];
+ wrT = MAX(0.0,MIN(1.0,wrT));
+ wrT = pow(wrT, 0.5*powerT[itype][jtype]);
+ double randnumT = randomT->gaussian();
+ randnumT = MAX(-5.0,MIN(randnum,5.0));
+
+ double kappaT = kappa[itype][jtype];
+ if(kappa_flag) {
+ double factor = 1.0;
+ for(int k = 0; k < 4; k++)
+ factor += kc[itype][jtype][k]*T_pow[k];
+ kappaT *= factor;
+ }
+
+ double kij = cv[i]*cv[j]*kappaT * T_ij*T_ij;
+ double alphaij = sqrt(2.0*kboltz*kij);
+
+ dQc = kij * wrT*wrT * ( T[j] - T[i] )/(T[i]*T[j]);
+ dQd = wr*wr*( GammaIJ * vijeij*vijeij - SigmaIJ*SigmaIJ/mass[itype] ) - SigmaIJ * wr *vijeij *randnum;
+ dQd /= (cv[i]+cv[j]);
+ dQr = alphaij * wrT * dtinvsqrt * randnumT;
+ Q[i] += (dQc + dQd + dQr );
+ }
+ //-----------------------------------------------------------
+
+ if (newton_pair || j < nlocal) {
+ f[j][0] -= delx*fpair;
+ f[j][1] -= dely*fpair;
+ f[j][2] -= delz*fpair;
+ Q[j] -= ( dQc - dQd + dQr );
+ }
+
+ if (eflag) {
+ evdwl = 0.5*a0[itype][jtype]*T_ij*cut[itype][jtype] * wc*wc;
+ evdwl *= factor_dpd;
+ }
+
+ 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 PairEDPD::allocate()
+{
+ int i,j;
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (i = 1; i <= n; i++)
+ for (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(cutT,n+1,n+1,"pair:cutT");
+ memory->create(a0,n+1,n+1,"pair:a0");
+ memory->create(gamma,n+1,n+1,"pair:gamma");
+ memory->create(power,n+1,n+1,"pair:power");
+ memory->create(kappa,n+1,n+1,"pair:kappa");
+ memory->create(powerT,n+1,n+1,"pair:powerT");
+
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairEDPD::settings(int narg, char **arg)
+{
+ if (narg != 2) error->all(FLERR,"Illegal pair_style command");
+
+ cut_global = force->numeric(FLERR,arg[0]);
+ seed = force->inumeric(FLERR,arg[1]);
+
+ // initialize Marsaglia RNG with processor-unique seed
+
+ if (seed <= 0 ) {
+ struct timespec time;
+ clock_gettime( CLOCK_REALTIME, &time );
+ seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed
+ }
+ delete random;
+ random = new RanMars(lmp,(seed + comm->me) % 900000000);
+ randomT = new RanMars(lmp,(2*seed + comm->me) % 900000000);
+
+ // 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 PairEDPD::coeff(int narg, char **arg)
+{
+ if (narg < 9)
+ error->all(FLERR,"Incorrect args for pair edpd coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi);
+
+ double a0_one = force->numeric(FLERR,arg[2]);
+ double gamma_one = force->numeric(FLERR,arg[3]);
+ double power_one = force->numeric(FLERR,arg[4]);
+ double cut_one = force->numeric(FLERR,arg[5]);
+ double kappa_one = force->numeric(FLERR,arg[6]);
+ double powerT_one= force->numeric(FLERR,arg[7]);
+ double cutT_one = force->numeric(FLERR,arg[8]);
+
+ int iarg = 9;
+ power_flag = kappa_flag = 0;
+ double sc_one[4], kc_one[4];
+ int n = atom->ntypes;
+ while (iarg < narg) {
+ if (strcmp(arg[iarg],"power") == 0) {
+ if (iarg+5 > narg) error->all(FLERR,"Illegal pair edpd coefficients");
+ for (int i = 0; i < 4; i++)
+ sc_one[i] = force->numeric(FLERR,arg[iarg+i+1]);
+ iarg += 5;
+ power_flag = 1;
+ memory->create(sc,n+1,n+1,4,"pair:sc");
+ } else if (strcmp(arg[iarg],"kappa") == 0) {
+ if (iarg+5 > narg) error->all(FLERR,"Illegal pair edpd coefficients");
+ for (int i = 0; i < 4; i++)
+ kc_one[i] = force->numeric(FLERR,arg[iarg+i+1]);
+ iarg += 5;
+ kappa_flag = 1;
+ memory->create(kc,n+1,n+1,4,"pair:kc");
+ } else error->all(FLERR,"Illegal pair edpd coefficients");
+ }
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++)
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ a0[i][j] = a0_one;
+ gamma[i][j] = gamma_one;
+ power[i][j] = power_one;
+ cut[i][j] = cut_one;
+ kappa[i][j] = kappa_one;
+ powerT[i][j]= powerT_one;
+ cutT[i][j] = cutT_one;
+
+ if(power_flag)
+ for (int k = 0; k < 4; k++)
+ sc[i][j][k] = sc_one[k];
+
+ if(kappa_flag)
+ for (int k = 0; k < 4; k++)
+ kc[i][j][k] = kc_one[k];
+
+ setflag[i][j] = 1;
+ count++;
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairEDPD::init_style()
+{
+ if (comm->ghost_velocity == 0)
+ error->all(FLERR,"Pair edpd requires ghost atoms store velocity");
+
+ // if newton off, forces between atoms ij will be double computed
+ // using different random numbers
+
+ if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR,
+ "Pair tdpd needs newton pair on for momentum conservation");
+
+ neighbor->request(this,instance_me);
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairEDPD::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ cut[j][i] = cut[i][j];
+ cutT[j][i] = cutT[i][j];
+ a0[j][i] = a0[i][j];
+ gamma[j][i] = gamma[i][j];
+ power[j][i] = power[i][j];
+ kappa[j][i] = kappa[i][j];
+ powerT[j][i]= powerT[i][j];
+
+ if(power_flag)
+ for (int k = 0; k < 4; k++)
+ sc[j][i][k] = sc[i][j][k];
+
+ if(kappa_flag)
+ for (int k = 0; k < 4; k++)
+ kc[j][i][k] = kc[i][j][k];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairEDPD::write_restart(FILE *fp)
+{
+ write_restart_settings(fp);
+
+ for (int i = 1; i <= atom->ntypes; i++)
+ for (int j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&a0[i][j],sizeof(double),1,fp);
+ fwrite(&gamma[i][j],sizeof(double),1,fp);
+ fwrite(&power[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ fwrite(&kappa[i][j],sizeof(double),1,fp);
+ fwrite(&powerT[i][j],sizeof(double),1,fp);
+ fwrite(&cutT[i][j],sizeof(double),1,fp);
+ if(power_flag)
+ for (int k = 0; k < 4; k++)
+ fwrite(&sc[i][j][k],sizeof(double),1,fp);
+
+ if(kappa_flag)
+ for (int k = 0; k < 4; k++)
+ fwrite(&kc[i][j][k],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairEDPD::read_restart(FILE *fp)
+{
+ read_restart_settings(fp);
+
+ allocate();
+
+ int me = comm->me;
+ for (int i = 1; i <= atom->ntypes; i++)
+ for (int 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(&a0[i][j],sizeof(double),1,fp);
+ fread(&gamma[i][j],sizeof(double),1,fp);
+ fread(&power[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ fread(&kappa[i][j],sizeof(double),1,fp);
+ fread(&powerT[i][j],sizeof(double),1,fp);
+ fread(&cutT[i][j],sizeof(double),1,fp);
+ if(power_flag)
+ for (int k = 0; k < 4; k++)
+ fread(&sc[i][j][k],sizeof(double),1,fp);
+
+ if(kappa_flag)
+ for (int k = 0; k < 4; k++)
+ fread(&kc[i][j][k],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&a0[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&gamma[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&power[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&kappa[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&powerT[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cutT[i][j],1,MPI_DOUBLE,0,world);
+ if(power_flag)
+ for (int k = 0; k < 4; k++)
+ MPI_Bcast(&sc[i][j][k],1,MPI_DOUBLE,0,world);
+
+ if(kappa_flag)
+ for (int k = 0; k < 4; k++)
+ MPI_Bcast(&kc[i][j][k],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairEDPD::write_restart_settings(FILE *fp)
+{
+ fwrite(&cut_global,sizeof(double),1,fp);
+ fwrite(&seed,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairEDPD::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&seed,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&seed,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+
+ // initialize Marsaglia RNG with processor-unique seed
+ // same seed that pair_style command initially specified
+
+ if (random) delete random;
+ random = new RanMars(lmp,seed + comm->me);
+ if (randomT) delete randomT;
+ randomT = new RanMars(lmp,seed + comm->me);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairEDPD::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_dpd, double &fforce)
+{
+ double r,rinv,wc,phi;
+ double *T = atom->edpd_temp;
+
+ r = sqrt(rsq);
+ if (r < EPSILON) {
+ fforce = 0.0;
+ return 0.0;
+ }
+ double T_ij = 0.5*(T[i]+T[j]);
+ rinv = 1.0/r;
+ wc = 1.0 - r/cut[itype][jtype];
+ fforce = a0[itype][jtype]*T_ij*wc*factor_dpd*rinv;
+
+ phi = 0.5*a0[itype][jtype]*T_ij*cut[itype][jtype]*wc*wc;
+ return factor_dpd*phi;
+}
diff --git a/src/USER-MESO/pair_edpd.h b/src/USER-MESO/pair_edpd.h
new file mode 100644
index 0000000000..9ab0ad9670
--- /dev/null
+++ b/src/USER-MESO/pair_edpd.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(edpd,PairEDPD)
+
+#else
+
+#ifndef LMP_PAIR_EDPD_H
+#define LMP_PAIR_EDPD_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairEDPD : public Pair {
+ public:
+ PairEDPD(class LAMMPS *);
+ virtual ~PairEDPD();
+ virtual void compute(int, int);
+ virtual void settings(int, char **);
+ virtual void coeff(int, char **);
+ void init_style();
+ 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 *);
+ double single(int, int, int, int, double, double, double, double &);
+
+ protected:
+ double cut_global;
+ int seed;
+ double **cut,**cutT;
+ double **a0,**gamma;
+ double **power;
+ double **slope;
+ double **kappa;
+ double **powerT;
+ int power_flag, kappa_flag;
+ double ***sc,***kc;
+ class RanMars *random;
+ class RanMars *randomT;
+
+ void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Incorrect args for pair coefficients
+
+Self-explanatory. Check the input script or data file.
+
+W: Pair tdpd needs newton pair on for momentum conservation
+
+Self-explanatory.
+
+E: All pair coeffs are not set
+
+All pair coefficients must be set in the data file or by the
+pair_coeff command before running a simulation.
+
+*/
diff --git a/src/USER-MESO/pair_mdpd.cpp b/src/USER-MESO/pair_mdpd.cpp
new file mode 100644
index 0000000000..bf78ea5af7
--- /dev/null
+++ b/src/USER-MESO/pair_mdpd.cpp
@@ -0,0 +1,425 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain 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: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+#include "pair_mdpd.h"
+#include "atom.h"
+#include "atom_vec.h"
+#include "comm.h"
+#include "update.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "random_mars.h"
+#include "citeme.h"
+#include "memory.h"
+#include "error.h"
+#include
+
+using namespace LAMMPS_NS;
+
+#define EPSILON 1.0e-10
+
+static const char cite_pair_mdpd[] =
+ "pair mdpd command:\n\n"
+ "@Article{ZLi2013_POF,\n"
+ " author = {Li, Z. and Hu, G.H. and Wang, Z.L. and Ma Y.B. and Zhou, Z.W.},\n"
+ " title = {Three dimensional flow structures in a moving droplet on substrate: a dissipative particle dynamics study},\n"
+ " journal = {Physics of Fluids},\n"
+ " year = {2013},\n"
+ " volume = {25},\n"
+ " pages = {072103}\n"
+ "}\n\n";
+
+/* ---------------------------------------------------------------------- */
+
+PairMDPD::PairMDPD(LAMMPS *lmp) : Pair(lmp)
+{
+ if (lmp->citeme) lmp->citeme->add(cite_pair_mdpd);
+
+ writedata = 1;
+ random = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairMDPD::~PairMDPD()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(cut_r);
+ memory->destroy(A_att);
+ memory->destroy(B_rep);
+ memory->destroy(gamma);
+ memory->destroy(sigma);
+ }
+ if (random) delete random;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMDPD::compute(int eflag, int vflag)
+{
+ int i,j,ii,jj,inum,jnum,itype,jtype;
+ double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
+ double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
+ double rsq,r,rinv,dot,wc,wc_r, wr,randnum,factor_dpd;
+ int *ilist,*jlist,*numneigh,**firstneigh;
+ double rhoi, rhoj;
+
+ evdwl = 0.0;
+ 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 *rho= atom->rho;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ int newton_pair = force->newton_pair;
+ double dtinvsqrt = 1.0/sqrt(update->dt);
+
+ 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];
+ vxtmp = v[i][0];
+ vytmp = v[i][1];
+ vztmp = v[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+ rhoi = rho[i];
+ 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 MDPD 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;
+
+ wc = 1.0 - r/cut[itype][jtype];
+ wc_r = 1.0 - r/cut_r[itype][jtype];
+ wc_r = MAX(wc_r,0.0);
+ wr = wc;
+
+ rhoj = rho[j];
+ randnum = random->gaussian();
+
+ // conservative force = A_att * wc + B_rep*(rhoi+rhoj)*wc_r
+ // drag force = -gamma * wr^2 * (delx dot delv) / r
+ // random force = sigma * wr * rnd * dtinvsqrt;
+
+ fpair = A_att[itype][jtype]*wc + B_rep[itype][jtype]*(rhoi+rhoj)*wc_r;
+ fpair -= gamma[itype][jtype]*wr*wr*dot*rinv;
+ fpair += sigma[itype][jtype]*wr*randnum*dtinvsqrt;
+ fpair *= factor_dpd*rinv;
+
+ 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) {
+ // unshifted eng of conservative term:
+ // eng shifted to 0.0 at cutoff
+ evdwl = 0.5*A_att[itype][jtype]*cut[itype][jtype] * wr*wr + 0.5*B_rep[itype][jtype]*cut_r[itype][jtype]*(rhoi+rhoj)*wc_r*wc_r;
+ evdwl *= factor_dpd;
+ }
+
+ 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 PairMDPD::allocate()
+{
+ int i,j;
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (i = 1; i <= n; i++)
+ for (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(cut_r,n+1,n+1,"pair:cut_r");
+ memory->create(A_att,n+1,n+1,"pair:A_att");
+ memory->create(B_rep,n+1,n+1,"pair:B_rep");
+ memory->create(gamma,n+1,n+1,"pair:gamma");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairMDPD::settings(int narg, char **arg)
+{
+ if (narg != 3) error->all(FLERR,"Illegal pair_style command");
+
+ temperature = force->numeric(FLERR,arg[0]);
+ cut_global = force->numeric(FLERR,arg[1]);
+ seed = force->inumeric(FLERR,arg[2]);
+
+ // initialize Marsaglia RNG with processor-unique seed
+
+ if (seed <= 0 ) {
+ struct timespec time;
+ clock_gettime( CLOCK_REALTIME, &time );
+ seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed
+ }
+ delete random;
+ random = new RanMars(lmp,(seed + comm->me) % 900000000);
+
+ // 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 PairMDPD::coeff(int narg, char **arg)
+{
+ if(narg != 7 ) error->all(FLERR,"Incorrect args for pair coefficients\n itype jtype A B gamma cutA cutB");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi);
+
+ double A_one = force->numeric(FLERR,arg[2]);
+ double B_one = force->numeric(FLERR,arg[3]);
+ double gamma_one = force->numeric(FLERR,arg[4]);
+ double cut_one = force->numeric(FLERR,arg[5]);
+ double cut_two = force->numeric(FLERR,arg[6]);
+
+ if(cut_one < cut_two) error->all(FLERR,"Incorrect args for pair coefficients\n cutA should be larger than cutB.");
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ A_att[i][j] = A_one;
+ B_rep[i][j] = B_one;
+ gamma[i][j] = gamma_one;
+ cut[i][j] = cut_one;
+ cut_r[i][j] = cut_two;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairMDPD::init_style()
+{
+ if (comm->ghost_velocity == 0)
+ error->all(FLERR,"Pair mdpd requires ghost atoms store velocity");
+
+ // if newton off, forces between atoms ij will be double computed
+ // using different random numbers
+
+ if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR,
+ "Pair mdpd needs newton pair on for momentum conservation");
+
+ neighbor->request(this,instance_me);
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairMDPD::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]);
+
+ cut[j][i] = cut[i][j];
+ cut_r[j][i] = cut_r[i][j];
+ A_att[j][i] = A_att[i][j];
+ B_rep[j][i] = B_rep[i][j];
+ gamma[j][i] = gamma[i][j];
+ sigma[j][i] = sigma[i][j];
+
+ return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairMDPD::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_att[i][j],sizeof(double),1,fp);
+ fwrite(&B_rep[i][j],sizeof(double),1,fp);
+ fwrite(&gamma[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ fwrite(&cut_r[i][j],sizeof(double),1,fp);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairMDPD::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_att[i][j],sizeof(double),1,fp);
+ fread(&B_rep[i][j],sizeof(double),1,fp);
+ fread(&gamma[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ fread(&cut_r[i][j],sizeof(double),1,fp);
+ }
+ MPI_Bcast(&A_att[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&B_rep[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&gamma[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_r[i][j],1,MPI_DOUBLE,0,world);
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairMDPD::write_restart_settings(FILE *fp)
+{
+ fwrite(&temperature,sizeof(double),1,fp);
+ fwrite(&cut_global,sizeof(double),1,fp);
+ fwrite(&seed,sizeof(int),1,fp);
+ fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairMDPD::read_restart_settings(FILE *fp)
+{
+ if (comm->me == 0) {
+ fread(&temperature,sizeof(double),1,fp);
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&seed,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&temperature,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&seed,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+
+ // initialize Marsaglia RNG with processor-unique seed
+ // same seed that pair_style command initially specified
+
+ if (random) delete random;
+ random = new RanMars(lmp,seed + comm->me);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes to data file
+------------------------------------------------------------------------- */
+
+void PairMDPD::write_data(FILE *fp)
+{
+ for (int i = 1; i <= atom->ntypes; i++)
+ fprintf(fp,"%d %g %g %g\n",i,A_att[i][i],B_rep[i][i],gamma[i][i]);
+}
+
+/* ----------------------------------------------------------------------
+ proc 0 writes all pairs to data file
+------------------------------------------------------------------------- */
+
+void PairMDPD::write_data_all(FILE *fp)
+{
+ for (int i = 1; i <= atom->ntypes; i++)
+ for (int j = i; j <= atom->ntypes; j++)
+ fprintf(fp,"%d %d %g %g %g %g %g\n",i,j,A_att[i][j],B_rep[i][j],gamma[i][j],cut[i][j],cut_r[i][j]);
+}
+
diff --git a/src/USER-MESO/pair_mdpd.h b/src/USER-MESO/pair_mdpd.h
new file mode 100644
index 0000000000..ea0389c7fe
--- /dev/null
+++ b/src/USER-MESO/pair_mdpd.h
@@ -0,0 +1,84 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(mdpd,PairMDPD)
+
+#else
+
+#ifndef LMP_PAIR_MDPD_H
+#define LMP_PAIR_MDPD_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairMDPD : public Pair {
+ public:
+ PairMDPD(class LAMMPS *);
+ virtual ~PairMDPD();
+ virtual void compute(int, int);
+ virtual void settings(int, char **);
+ virtual void coeff(int, char **);
+ void init_style();
+ 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 void write_data(FILE *);
+ virtual void write_data_all(FILE *);
+
+ protected:
+ double cut_global,temperature;
+ int seed;
+ double **cut, **cut_r;
+ double **A_att,**B_rep;
+ double **gamma,**sigma;
+ class RanMars *random;
+
+ void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Incorrect args for pair coefficients
+
+Self-explanatory. Check the input script or data file.
+
+E: Pair dpd requires ghost atoms store velocity
+
+Use the comm_modify vel yes command to enable this.
+
+W: Pair dpd needs newton pair on for momentum conservation
+
+Self-explanatory.
+
+E: All pair coeffs are not set
+
+All pair coefficients must be set in the data file or by the
+pair_coeff command before running a simulation.
+
+*/
diff --git a/src/USER-MESO/pair_mdpd_rhosum.cpp b/src/USER-MESO/pair_mdpd_rhosum.cpp
new file mode 100644
index 0000000000..9c4d6f804f
--- /dev/null
+++ b/src/USER-MESO/pair_mdpd_rhosum.cpp
@@ -0,0 +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.
+ ------------------------------------------------------------------------- */
+
+/*-----------------------------------------------------------------------
+ This is a Child Class PairMDPD for taking care of density summation
+ before the force calculation.
+ The code uses 3D Lucy kernel, it can be modified for other kernels.
+
+ Contributing author: Zhen Li (Brown University)
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include "pair_mdpd_rhosum.h"
+#include "atom.h"
+#include "force.h"
+#include "comm.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "memory.h"
+#include "error.h"
+#include "neighbor.h"
+#include "update.h"
+#include "domain.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+PairMDPDRhoSum::PairMDPDRhoSum(LAMMPS *lmp) : Pair(lmp)
+{
+ restartinfo = 0;
+
+ // set comm size needed by this Pair
+
+ comm_forward = 1;
+ first = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairMDPDRhoSum::~PairMDPDRhoSum() {
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ }
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+ ------------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::init_style() {
+ // need a full neighbor list
+ int irequest = neighbor->request(this,instance_me);
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->full = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::compute(int eflag, int vflag) {
+ int i, j, ii, jj, jnum, itype, jtype;
+ double xtmp, ytmp, ztmp, delx, dely, delz;
+ double r, rsq, h, ih, ihsq;
+ int *jlist;
+ double wf;
+ // neighbor list variables
+ int inum, *ilist, *numneigh, **firstneigh;
+
+ if (eflag || vflag)
+ ev_setup(eflag, vflag);
+ else
+ evflag = vflag_fdotr = 0;
+
+ double **x = atom->x;
+ double *rho = atom->rho;
+ int *type = atom->type;
+ double *mass = atom->mass;
+
+ // check consistency of pair coefficients
+ if (first) {
+ for (i = 1; i <= atom->ntypes; i++)
+ for (j = 1; i <= atom->ntypes; i++)
+ if (cutsq[i][j] > 0.0)
+ if (!setflag[i][i] || !setflag[j][j])
+ if (comm->me == 0)
+ printf("mDPD particle types %d and %d interact, but not all of their single particle properties are set.\n", i, j);
+
+ first = 0;
+ }
+
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ // recompute density
+ // we use a full neighborlist here
+
+ // initialize density with zero self-contribution,
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ itype = type[i];
+
+ h = cut[itype][itype];
+ // Lucy kernel, 3d
+ wf = 2.0889086280811262819e0 / (h * h * h);
+ rho[i] = 0;
+ }
+
+ // add density at each atom via kernel function overlap
+ for (ii = 0; ii < inum; ii++) {
+ i = ilist[ii];
+ xtmp = x[i][0];
+ ytmp = x[i][1];
+ ztmp = x[i][2];
+ itype = type[i];
+ jlist = firstneigh[i];
+ jnum = numneigh[i];
+
+ for (jj = 0; jj < jnum; jj++) {
+ j = jlist[jj];
+ j &= NEIGHMASK;
+
+ jtype = type[j];
+ delx = xtmp - x[j][0];
+ dely = ytmp - x[j][1];
+ delz = ztmp - x[j][2];
+ rsq = delx * delx + dely * dely + delz * delz;
+
+ if (rsq < cutsq[itype][jtype]) {
+ h = cut[itype][jtype];
+ ih = 1.0 / h;
+ ihsq = ih * ih;
+
+ // Lucy kernel, 3d
+ r = sqrt(rsq);
+ wf = (h - r) * ihsq;
+ wf = 2.0889086280811262819e0 * (h + 3. * r) * wf * wf * wf * ih;
+ rho[i] += mass[jtype]*wf;
+ }
+ }
+ }
+
+ // communicate densities
+ comm->forward_comm_pair(this);
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+ ------------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::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");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+ ------------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::settings(int narg, char **arg) {
+ if (narg != 0)
+ error->all(FLERR,"Illegal number of setting arguments for pair_style mdpd/rhosum");
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs
+ ------------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::coeff(int narg, char **arg) {
+ if (narg != 3)
+ error->all(FLERR,"Incorrect number of args for mdpd/rhosum coefficients");
+ if (!allocated)
+ allocate();
+
+ int ilo, ihi, jlo, jhi;
+ force->bounds(FLERR,arg[0], atom->ntypes, ilo, ihi);
+ force->bounds(FLERR,arg[1], atom->ntypes, jlo, jhi);
+
+ double cut_one = force->numeric(FLERR,arg[2]);
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++) {
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ cut[i][j] = cut_one;
+ setflag[i][j] = 1;
+ count++;
+ }
+ }
+
+ if (count == 0)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+ ------------------------------------------------------------------------- */
+
+double PairMDPDRhoSum::init_one(int i, int j) {
+ if (setflag[i][j] == 0) {
+ error->all(FLERR,"All pair mdpd/rhosum coeffs are not set");
+ }
+
+ cut[j][i] = cut[i][j];
+
+ return cut[i][j];
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairMDPDRhoSum::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_lj, double &fforce) {
+ fforce = 0.0;
+
+ return 0.0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int PairMDPDRhoSum::pack_forward_comm(int n, int *list, double *buf,
+ int pbc_flag, int *pbc) {
+ int i, j, m;
+ double *rho = atom->rho;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = rho[j];
+ }
+ return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairMDPDRhoSum::unpack_forward_comm(int n, int first, double *buf) {
+ int i, m, last;
+ double *rho = atom->rho;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++)
+ rho[i] = buf[m++];
+}
diff --git a/src/USER-MESO/pair_mdpd_rhosum.h b/src/USER-MESO/pair_mdpd_rhosum.h
new file mode 100644
index 0000000000..a972ec7ccf
--- /dev/null
+++ b/src/USER-MESO/pair_mdpd_rhosum.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(mdpd/rhosum,PairMDPDRhoSum)
+
+#else
+
+#ifndef LMP_PAIR_MDPD_RHOSUM_H
+#define LMP_PAIR_MDPD_RHOSUM_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairMDPDRhoSum : public Pair {
+ public:
+ PairMDPDRhoSum(class LAMMPS *);
+ virtual ~PairMDPDRhoSum();
+ void init_style();
+ virtual void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ virtual double init_one(int, int);
+ virtual double single(int, int, int, int, double, double, double, double &);
+ int pack_forward_comm(int, int *, double *, int, int *);
+ void unpack_forward_comm(int, int, double *);
+
+ protected:
+ double **cut;
+ int first;
+
+ void allocate();
+};
+
+}
+
+#endif
+#endif
diff --git a/src/USER-MESO/pair_tdpd.cpp b/src/USER-MESO/pair_tdpd.cpp
new file mode 100644
index 0000000000..1f2bd4eb6c
--- /dev/null
+++ b/src/USER-MESO/pair_tdpd.cpp
@@ -0,0 +1,476 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain 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: Zhen Li (Brown University)
+ Email: zhen_li@brown.edu
+------------------------------------------------------------------------- */
+
+#include
+#include
+#include
+#include "pair_tdpd.h"
+#include "atom.h"
+#include "atom_vec.h"
+#include "comm.h"
+#include "update.h"
+#include "force.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "random_mars.h"
+#include "citeme.h"
+#include "memory.h"
+#include "error.h"
+#include
+
+using namespace LAMMPS_NS;
+
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#define MAX(A,B) ((A) > (B) ? (A) : (B))
+
+#define EPSILON 1.0e-10
+
+static const char cite_pair_tdpd[] =
+ "pair tdpd command:\n\n"
+ "@Article{ZLi2015_JCP,\n"
+ " author = {Li, Z. and Yazdani, A. and Tartakovsky, A. and Karniadakis, G.E.},\n"
+ " title = {Transport dissipative particle dynamics model for mesoscopic advection-diffusion-reaction problems},\n"
+ " journal = {The Journal of Chemical Physics},\n"
+ " year = {2015},\n"
+ " volume = {143},\n"
+ " pages = {014101}\n"
+ "}\n\n";
+
+/* ---------------------------------------------------------------------- */
+
+PairTDPD::PairTDPD(LAMMPS *lmp) : Pair(lmp)
+{
+ if (lmp->citeme) lmp->citeme->add(cite_pair_tdpd);
+ cc_species = atom->cc_species;
+
+ writedata = 1;
+ random = NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+
+PairTDPD::~PairTDPD()
+{
+ if (allocated) {
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+
+ memory->destroy(cut);
+ memory->destroy(cutcc);
+
+ memory->destroy(a0);
+ memory->destroy(gamma);
+ memory->destroy(sigma);
+
+ memory->destroy(power);
+ memory->destroy(kappa);
+ memory->destroy(epsilon);
+ memory->destroy(powercc);
+ }
+
+ if (random) delete random;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairTDPD::compute(int eflag, int vflag)
+{
+ double evdwl = 0.0;
+ 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 **cc = atom->cc;
+ double **cc_flux = atom->cc_flux;
+ int *type = atom->type;
+ int nlocal = atom->nlocal;
+ double *special_lj = force->special_lj;
+ int newton_pair = force->newton_pair;
+ double dtinvsqrt = 1.0/sqrt(update->dt);
+
+ int inum = list->inum;
+ int *ilist = list->ilist;
+ int *numneigh = list->numneigh;
+ int **firstneigh = list->firstneigh;
+
+ // loop over neighbors of my atoms
+ for (int ii = 0; ii < inum; ii++) {
+ int i = ilist[ii];
+ double xtmp = x[i][0];
+ double ytmp = x[i][1];
+ double ztmp = x[i][2];
+ double vxtmp = v[i][0];
+ double vytmp = v[i][1];
+ double vztmp = v[i][2];
+ int itype = type[i];
+ int *jlist = firstneigh[i];
+ int jnum = numneigh[i];
+
+ for (int jj = 0; jj < jnum; jj++) {
+ int j = jlist[jj];
+ double factor_dpd = special_lj[sbmask(j)];
+ j &= NEIGHMASK;
+
+ double delx = xtmp - x[j][0];
+ double dely = ytmp - x[j][1];
+ double delz = ztmp - x[j][2];
+ double rsq = delx*delx + dely*dely + delz*delz;
+ int jtype = type[j];
+
+ if (rsq < cutsq[itype][jtype]) {
+ double r = sqrt(rsq);
+ if (r < EPSILON) continue; // r can be 0.0 in DPD systems
+ double rinv = 1.0/r;
+ double delvx = vxtmp - v[j][0];
+ double delvy = vytmp - v[j][1];
+ double delvz = vztmp - v[j][2];
+ double dot = delx*delvx + dely*delvy + delz*delvz;
+ double wc = 1.0 - r/cut[itype][jtype];
+ wc = MAX(0,MIN(1.0,wc));
+ double wr = pow(wc, 0.5*power[itype][jtype]);
+ double randnum = random->gaussian();
+
+ // conservative force = a0 * wc
+ // drag force = -gamma * wr^2 * (delx dot delv) / r
+ // random force = sigma * wr^(power/2) * rnd * dtinvsqrt;
+
+ double fpair = a0[itype][jtype]*wc;
+ fpair -= gamma[itype][jtype]*wr*wr*dot*rinv;
+ fpair += sigma[itype][jtype]*wr*randnum*dtinvsqrt;
+ fpair *= factor_dpd*rinv;
+
+ f[i][0] += delx*fpair;
+ f[i][1] += dely*fpair;
+ f[i][2] += delz*fpair;
+
+ // chemical concentration transport
+ if( r < cutcc[itype][jtype]) {
+ for(int k=0; kgaussian();
+ randnum = MAX(-5.0,MIN(randnum,5.0));
+ double dQc = -kappa[itype][jtype][k] * wcr*wcr *(cc[i][k]-cc[j][k]);
+ double dQr = epsilon[itype][jtype][k] *wcr* (cc[i][k]+cc[j][k]) *randnum*dtinvsqrt;
+ cc_flux[i][k] += (dQc + dQr);
+ if (newton_pair || j < nlocal)
+ cc_flux[j][k] -= ( dQc + dQr );
+ }
+ }
+ //-----------------------------------------------------------
+
+ 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*a0[itype][jtype]*cut[itype][jtype] * wc*wc;
+ evdwl *= factor_dpd;
+ }
+
+ 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 PairTDPD::allocate()
+{
+ int i,j;
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ for (i = 1; i <= n; i++)
+ for (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(cutcc,n+1,n+1,"pair:cutcc");
+ memory->create(a0,n+1,n+1,"pair:a0");
+ memory->create(gamma,n+1,n+1,"pair:gamma");
+ memory->create(sigma,n+1,n+1,"pair:sigma");
+ memory->create(power,n+1,n+1,"pair:power");
+ memory->create(kappa,n+1,n+1,cc_species,"pair:kappa");
+ memory->create(epsilon,n+1,n+1,cc_species,"pair:epsilon");
+ memory->create(powercc,n+1,n+1,cc_species,"pair:powercc");
+
+ for (i = 0; i <= atom->ntypes; i++)
+ for (j = 0; j <= atom->ntypes; j++)
+ sigma[i][j] = gamma[i][j] = 0.0;
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairTDPD::settings(int narg, char **arg)
+{
+ if (narg != 3) error->all(FLERR,"Illegal pair_style command");
+
+ temperature = force->numeric(FLERR,arg[0]);
+ cut_global = force->numeric(FLERR,arg[1]);
+ seed = force->inumeric(FLERR,arg[2]);
+
+ // initialize Marsaglia RNG with processor-unique seed
+
+ if (seed <= 0 ) {
+ struct timespec time;
+ clock_gettime( CLOCK_REALTIME, &time );
+ seed = time.tv_nsec; // if seed is non-positive, get the current time as the seed
+ }
+ delete random;
+ random = new RanMars(lmp,(seed + comm->me) % 900000000);
+
+ // 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 PairTDPD::coeff(int narg, char **arg)
+{
+ if (narg != 7 + 3*cc_species)
+ error->all(FLERR,"Incorrect args for pair tdpd coefficients");
+ if (!allocated) allocate();
+
+ int ilo,ihi,jlo,jhi;
+ force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi);
+ force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi);
+
+ double a0_one = force->numeric(FLERR,arg[2]);
+ double gamma_one = force->numeric(FLERR,arg[3]);
+ double power_one = force->numeric(FLERR,arg[4]);
+ double cut_one = force->numeric(FLERR,arg[5]);
+ double cutcc_one = force->numeric(FLERR,arg[6]);
+ double kappa_one[cc_species],epsilon_one[cc_species],powercc_one[cc_species];
+ for(int k=0; knumeric(FLERR,arg[7+3*k]);
+ epsilon_one[k] = force->numeric(FLERR,arg[8+3*k]);
+ powercc_one[k] = force->numeric(FLERR,arg[9+3*k]);
+ }
+
+ int count = 0;
+ for (int i = ilo; i <= ihi; i++)
+ for (int j = MAX(jlo,i); j <= jhi; j++) {
+ a0[i][j] = a0_one;
+ gamma[i][j] = gamma_one;
+ power[i][j] = power_one;
+ cut[i][j] = cut_one;
+ cutcc[i][j] = cutcc_one;
+ for(int k=0; kall(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairTDPD::init_style()
+{
+ if (comm->ghost_velocity == 0)
+ error->all(FLERR,"Pair tdpd requires ghost atoms store velocity");
+
+ // if newton off, forces between atoms ij will be double computed
+ // using different random numbers
+
+ if (force->newton_pair == 0 && comm->me == 0) error->warning(FLERR,
+ "Pair tdpd needs newton pair on for momentum conservation");
+
+ neighbor->request(this,instance_me);
+}
+
+/* ----------------------------------------------------------------------
+ init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairTDPD::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ sigma[i][j] = sqrt(2.0*force->boltz*temperature*gamma[i][j]);
+
+ cut[j][i] = cut[i][j];
+ cutcc[j][i] = cutcc[i][j];
+ a0[j][i] = a0[i][j];
+ gamma[j][i] = gamma[i][j];
+ sigma[j][i] = sigma[i][j];
+ power[j][i] = power[i][j];
+ for(int k=0; kntypes; i++)
+ for (int j = i; j <= atom->ntypes; j++) {
+ fwrite(&setflag[i][j],sizeof(int),1,fp);
+ if (setflag[i][j]) {
+ fwrite(&a0[i][j],sizeof(double),1,fp);
+ fwrite(&gamma[i][j],sizeof(double),1,fp);
+ fwrite(&power[i][j],sizeof(double),1,fp);
+ fwrite(&cut[i][j],sizeof(double),1,fp);
+ fwrite(&cutcc[i][j],sizeof(double),1,fp);
+ for(int k=0; kme;
+ for (int i = 1; i <= atom->ntypes; i++)
+ for (int 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(&a0[i][j],sizeof(double),1,fp);
+ fread(&gamma[i][j],sizeof(double),1,fp);
+ fread(&power[i][j],sizeof(double),1,fp);
+ fread(&cut[i][j],sizeof(double),1,fp);
+ fread(&cutcc[i][j],sizeof(double),1,fp);
+ for(int k=0; kme == 0) {
+ fread(&temperature,sizeof(double),1,fp);
+ fread(&cut_global,sizeof(double),1,fp);
+ fread(&seed,sizeof(int),1,fp);
+ fread(&mix_flag,sizeof(int),1,fp);
+ }
+ MPI_Bcast(&temperature,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&seed,1,MPI_INT,0,world);
+ MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+
+ // initialize Marsaglia RNG with processor-unique seed
+ // same seed that pair_style command initially specified
+
+ if (random) delete random;
+ random = new RanMars(lmp,seed + comm->me);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairTDPD::single(int i, int j, int itype, int jtype, double rsq,
+ double factor_coul, double factor_dpd, double &fforce)
+{
+ double r,rinv,wc,phi;
+
+ r = sqrt(rsq);
+ if (r < EPSILON) {
+ fforce = 0.0;
+ return 0.0;
+ }
+
+ rinv = 1.0/r;
+ wc = 1.0 - r/cut[itype][jtype];
+ fforce = a0[itype][jtype]*wc*factor_dpd*rinv;
+
+ phi = 0.5*a0[itype][jtype]*cut[itype][jtype]*wc*wc;
+ return factor_dpd*phi;
+}
diff --git a/src/USER-MESO/pair_tdpd.h b/src/USER-MESO/pair_tdpd.h
new file mode 100644
index 0000000000..9245308d38
--- /dev/null
+++ b/src/USER-MESO/pair_tdpd.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ http://lammps.sandia.gov, Sandia National Laboratories
+ Steve Plimpton, sjplimp@sandia.gov
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(tdpd,PairTDPD)
+
+#else
+
+#ifndef LMP_PAIR_TDPD_H
+#define LMP_PAIR_TDPD_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairTDPD : public Pair {
+ public:
+ PairTDPD(class LAMMPS *);
+ virtual ~PairTDPD();
+ virtual void compute(int, int);
+ virtual void settings(int, char **);
+ virtual void coeff(int, char **);
+ void init_style();
+ 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 *);
+ double single(int, int, int, int, double, double, double, double &);
+
+ protected:
+ double cut_global,temperature;
+ int seed,cc_species;
+ double **cut,**cutcc;
+ double **a0,**gamma,**sigma;
+ double **power;
+ double ***kappa,***epsilon;
+ double ***powercc;
+ class RanMars *random;
+
+ void allocate();
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Incorrect args for pair coefficients
+
+Self-explanatory. Check the input script or data file.
+
+W: Pair tdpd needs newton pair on for momentum conservation
+
+Self-explanatory.
+
+E: All pair coeffs are not set
+
+All pair coefficients must be set in the data file or by the
+pair_coeff command before running a simulation.
+
+*/
diff --git a/src/atom.cpp b/src/atom.cpp
index e46b1a7242..d4c00bc0a5 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -105,6 +105,11 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
dpdTheta = NULL;
ssaAIR = NULL;
+ // USER-MESO
+
+ cc = cc_flux = NULL;
+ edpd_temp = edpd_flux = edpd_cv = NULL;
+
// USER-SMD
contact_radius = NULL;
@@ -169,7 +174,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
cs_flag = csforce_flag = vforce_flag = etag_flag = 0;
rho_flag = e_flag = cv_flag = vest_flag = 0;
- dpd_flag = 0;
+ dpd_flag = edpd_flag = tdpd_flag = 0;
// USER-SMD
@@ -302,6 +307,12 @@ Atom::~Atom()
memory->destroy(duChem);
memory->destroy(ssaAIR);
+ memory->destroy(cc);
+ memory->destroy(cc_flux);
+ memory->destroy(edpd_temp);
+ memory->destroy(edpd_flux);
+ memory->destroy(edpd_cv);
+
memory->destroy(nspecial);
memory->destroy(special);
@@ -2194,6 +2205,7 @@ void *Atom::extract(char *name)
if (strcmp(name, "damage") == 0) return (void *) damage;
if (strcmp(name,"dpdTheta") == 0) return (void *) dpdTheta;
+ if (strcmp(name,"edpd_temp") == 0) return (void *) edpd_temp;
return NULL;
}
diff --git a/src/atom.h b/src/atom.h
index 0f84c8242f..29a1c5d69e 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -95,6 +95,13 @@ class Atom : protected Pointers {
int nspecies_dpd;
int *ssaAIR; // Shardlow Splitting Algorithm Active Interaction Region number
+ // USER-MESO package
+
+ double **cc, **cc_flux; // cc = chemical concentration
+ double *edpd_temp,*edpd_flux; // temperature and heat flux
+ double *edpd_cv; // heat capacity
+ int cc_species;
+
// molecular info
int **nspecial; // 0,1,2 = cumulative # of 1-2,1-3,1-4 neighs
@@ -138,7 +145,7 @@ class Atom : protected Pointers {
int vfrac_flag,spin_flag,eradius_flag,ervel_flag,erforce_flag;
int cs_flag,csforce_flag,vforce_flag,ervelforce_flag,etag_flag;
int rho_flag,e_flag,cv_flag,vest_flag;
- int dpd_flag;
+ int dpd_flag,edpd_flag,tdpd_flag;
// USER-SMD package
diff --git a/src/set.cpp b/src/set.cpp
index 59625b7e6c..2b1c0edee2 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -41,11 +41,12 @@ using namespace LAMMPS_NS;
using namespace MathConst;
enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT};
+
enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI,
DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,THETA_RANDOM,ANGMOM,OMEGA,
DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER,
- MESO_E,MESO_CV,MESO_RHO,SMD_MASS_DENSITY,SMD_CONTACT_RADIUS,DPDTHETA,
- INAME,DNAME};
+ MESO_E,MESO_CV,MESO_RHO,EDPD_TEMP,EDPD_CV,CC,SMD_MASS_DENSITY,
+ SMD_CONTACT_RADIUS,DPDTHETA,INAME,DNAME};
#define BIG INT_MAX
@@ -419,6 +420,46 @@ void Set::command(int narg, char **arg)
set(MESO_RHO);
iarg += 2;
+ } else if (strcmp(arg[iarg],"edpd/temp") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
+ if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0;
+ else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
+ else {
+ dvalue = force->numeric(FLERR,arg[iarg+1]);
+ if (dvalue < 0.0) error->all(FLERR,"Illegal set command");
+ }
+ if (!atom->edpd_flag)
+ error->all(FLERR,"Cannot set edpd/temp for this atom style");
+ set(EDPD_TEMP);
+ iarg += 2;
+
+ } else if (strcmp(arg[iarg],"edpd/cv") == 0) {
+ if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
+ if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0;
+ else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
+ else {
+ dvalue = force->numeric(FLERR,arg[iarg+1]);
+ if (dvalue < 0.0) error->all(FLERR,"Illegal set command");
+ }
+ if (!atom->edpd_flag)
+ error->all(FLERR,"Cannot set edpd/cv for this atom style");
+ set(EDPD_CV);
+ iarg += 2;
+
+ } else if (strcmp(arg[iarg],"cc") == 0) {
+ if (iarg+3 > narg) error->all(FLERR,"Illegal set command");
+ if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0;
+ else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
+ else {
+ cc_index = force->inumeric(FLERR,arg[iarg+1]);
+ dvalue = force->numeric(FLERR,arg[iarg+2]);
+ if (cc_index < 1) error->all(FLERR,"Illegal set command");
+ }
+ if (!atom->tdpd_flag)
+ error->all(FLERR,"Cannot set cc for this atom style");
+ set(CC);
+ iarg += 3;
+
} else if (strcmp(arg[iarg],"smd/mass/density") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) varparse(arg[iarg+1],1);
@@ -476,14 +517,28 @@ void Set::command(int narg, char **arg)
} else error->all(FLERR,"Illegal set command");
// statistics
+ // for CC option, include species index
MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
if (comm->me == 0) {
- if (screen) fprintf(screen," %d settings made for %s\n",
- allcount,arg[origarg]);
- if (logfile) fprintf(logfile," %d settings made for %s\n",
- allcount,arg[origarg]);
+
+ if (screen) {
+ if (strcmp(arg[origarg],"cc") == 0)
+ fprintf(screen," %d settings made for %s index %s\n",
+ allcount,arg[origarg],arg[origarg+1]);
+ else
+ fprintf(screen," %d settings made for %s\n",
+ allcount,arg[origarg]);
+ }
+ if (logfile) {
+ if (strcmp(arg[origarg],"cc") == 0)
+ fprintf(logfile," %d settings made for %s index %s\n",
+ allcount,arg[origarg],arg[origarg+1]);
+ else
+ fprintf(logfile," %d settings made for %s\n",
+ allcount,arg[origarg]);
+ }
}
}
@@ -663,6 +718,11 @@ void Set::set(int keyword)
else if (keyword == MESO_E) atom->e[i] = dvalue;
else if (keyword == MESO_CV) atom->cv[i] = dvalue;
else if (keyword == MESO_RHO) atom->rho[i] = dvalue;
+
+ else if (keyword == EDPD_TEMP) atom->edpd_temp[i] = dvalue;
+ else if (keyword == EDPD_CV) atom->edpd_cv[i] = dvalue;
+ else if (keyword == CC) atom->cc[i][cc_index-1] = dvalue;
+
else if (keyword == SMD_MASS_DENSITY) {
// set mass from volume and supplied mass density
atom->rmass[i] = atom->vfrac[i] * dvalue;
diff --git a/src/set.h b/src/set.h
index dfb06a2e12..5584e228ba 100644
--- a/src/set.h
+++ b/src/set.h
@@ -35,7 +35,8 @@ class Set : protected Pointers {
int style,ivalue,newtype,count,index_custom;
int ximage,yimage,zimage,ximageflag,yimageflag,zimageflag;
double dvalue,xvalue,yvalue,zvalue,wvalue,fraction;
-
+ int cc_index;
+
int varflag,varflag1,varflag2,varflag3,varflag4;
int ivar1,ivar2,ivar3,ivar4;
double *vec1,*vec2,*vec3,*vec4;