diff --git a/README b/README index 81b8310ea2fbeaaa683101e8a0187525275b7d34..1b1fececec1b3958b60383767fe42e8aae8a8750 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ This is the ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® DEM simulation engine, released by -DCS Computing Gmbh, Linz, Austria +DCS Computing GmbH, Linz, Austria www.dcs-computing.com, office@dcs-computing.com LIGGGHTS® is open-source, distributed under the terms of the GNU Public diff --git a/doc/Eqs/gran_model_hooke_hysteresis_1.png b/doc/Eqs/gran_model_hooke_hysteresis_1.png new file mode 100644 index 0000000000000000000000000000000000000000..e6791906fcb92bece49878b7c001316bd434303e Binary files /dev/null and b/doc/Eqs/gran_model_hooke_hysteresis_1.png differ diff --git a/doc/Eqs/gran_model_hooke_hysteresis_1.tex b/doc/Eqs/gran_model_hooke_hysteresis_1.tex new file mode 100644 index 0000000000000000000000000000000000000000..135e90faedf36c39457bc342a0af345666e97b18 --- /dev/null +++ b/doc/Eqs/gran_model_hooke_hysteresis_1.tex @@ -0,0 +1,9 @@ +\documentclass[12pt]{article} + +\begin{document} +\pagenumbering{gobble} +$$ + \delta^*_{max} = \frac{\hat k_2}{\hat k_2 - k_1} \phi_f \frac{2 r_i r_j}{r_i + r_j} +$$ + +\end{document} diff --git a/doc/Eqs/gran_model_hooke_hysteresis_2.png b/doc/Eqs/gran_model_hooke_hysteresis_2.png new file mode 100644 index 0000000000000000000000000000000000000000..587ad0f4887ed5c199556cf02298d0b56f30d01a Binary files /dev/null and b/doc/Eqs/gran_model_hooke_hysteresis_2.png differ diff --git a/doc/Eqs/gran_model_hooke_hysteresis_2.tex b/doc/Eqs/gran_model_hooke_hysteresis_2.tex new file mode 100644 index 0000000000000000000000000000000000000000..47d714da3b6d43acd442cc74069eb043c8931faf --- /dev/null +++ b/doc/Eqs/gran_model_hooke_hysteresis_2.tex @@ -0,0 +1,12 @@ +\documentclass[12pt]{article} + +\begin{document} +\pagenumbering{gobble} +$$ +k_2 := k_2 (\delta_{max}) = \left\{\begin{matrix} +\hat k_2 & \textup{if } \delta_{max} \geq \delta^*_{max} \\ +k_1 + (\hat k_2 - k_1 ) \frac{\delta_{max}}{\delta^*_{max}} & \textup{if } \delta_{max} < \delta^*_{max} +\end{matrix}\right. +$$ + +\end{document} diff --git a/doc/JPG/hooke_hysteresis_luding1.png b/doc/JPG/hooke_hysteresis_luding1.png new file mode 100644 index 0000000000000000000000000000000000000000..42e89089895cefb7d6f07a391304c627aac7c52b Binary files /dev/null and b/doc/JPG/hooke_hysteresis_luding1.png differ diff --git a/doc/Manual.html b/doc/Manual.html index 23789139b187a42e911d5c038d6e58cf7eda4295..3d3139015d0d96f573514fd60fed7ce91960b3a3 100644 --- a/doc/Manual.html +++ b/doc/Manual.html @@ -1,4 +1,5 @@ <HTML> +<!-- HTML_ONLY --> <HEAD> <TITLE>LIGGGHTS(R)-PUBLIC Users Manual</TITLE> <META NAME="docnumber" CONTENT="LIGGGHTS(R)-PUBLIC DEM simulation engine"> @@ -8,6 +9,8 @@ <BODY> +<!-- END_HTML_ONLY --> + <CENTER><A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> </CENTER> @@ -18,8 +21,7 @@ <HR> -<HR><H1></H1> - +<HR> <CENTER><H3>LIGGGHTS(R)-PUBLIC Documentation, Version 3.X </H3></CENTER> @@ -37,9 +39,8 @@ <HR> -<H4>LIGGGHTS(R)-PUBLIC is open-source, distributed under the terms of the GNU Public -License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: <A HREF = "http://www.liggghts.com">www.liggghts.com</A> | <A HREF = "http://www.cfdem.com">www.cfdem.com</A> -</H4> +<P>LIGGGHTS(R)-PUBLIC is open-source, distributed under the terms of the GNU Public License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: <A HREF = "http://www.liggghts.com">www.liggghts.com</A> | <A HREF = "http://www.cfdem.com">www.cfdem.com</A> +</P> @@ -47,12 +48,12 @@ License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: <A H <P>Core developer and main author: Christoph Kloss, christoph.kloss@dcs-computing.com </P> -<H4>LIGGGHTS(R)-PUBLIC is an Open Source Discrete Element Method Particle +<P><B>LIGGGHTS(R)-PUBLIC is an Open Source Discrete Element Method Particle Simulation Software, distributed by DCS Computing GmbH, Linz, Austria. LIGGGHTS (R) and CFDEM(R) are registered trade marks of DCS Computing GmbH, the producer of the LIGGGHTS (R) software and the CFDEM(R)coupling software -See http://www.cfdem.com/terms-trademark-policy for details. -</H4> +See http://www.cfdem.com/terms-trademark-policy for details.</B> +</P> <H4>LIGGGHTS (R) Version info: </H4> <P>All LIGGGHTS (R) versions are based on a specific version of LIGGGHTS (R), as printed in @@ -89,224 +90,5 @@ we can improve the LIGGGHTS(R)-PUBLIC documentation. page</A> since it gives quick access to documentation for all LIGGGHTS(R)-PUBLIC commands. </P> -<OL><LI><A HREF = "Section_intro.html">Introduction</A> - -<UL> 1.1 <A HREF = "Section_intro.html#intro_1">What is LIGGGHTS(R)-PUBLIC</A> -<BR> - 1.2 <A HREF = "Section_intro.html#intro_2">LIGGGHTS(R)-PUBLIC features</A> -<BR> - 1.3 <A HREF = "Section_intro.html#intro_3">Open source distribution</A> -<BR> - 1.4 <A HREF = "Section_intro.html#intro_4">Acknowledgments and citations</A> -<BR></UL> -<LI><A HREF = "Section_start.html">Getting started</A> - -<UL> 2.1 <A HREF = "Section_start.html#start_1">What's in the LIGGGHTS(R)-PUBLIC distribution</A> -<BR> - 2.2 <A HREF = "Section_start.html#start_2">Making LIGGGHTS(R)-PUBLIC</A> -<BR> - 2.3 <A HREF = "Section_start.html#start_3">Making LIGGGHTS(R)-PUBLIC with optional packages</A> -<BR> - 2.4 <A HREF = "Section_start.html#start_4">Building LIGGGHTS(R)-PUBLIC via the Make.py script</A> -<BR> - 2.5 <A HREF = "Section_start.html#start_5">Building LIGGGHTS(R)-PUBLIC as a library</A> -<BR> - 2.6 <A HREF = "Section_start.html#start_6">Running LIGGGHTS(R)-PUBLIC</A> -<BR> - 2.7 <A HREF = "Section_start.html#start_7">Command-line options</A> -<BR> - 2.8 <A HREF = "Section_start.html#start_8">Screen output</A> -<BR></UL> -<LI><A HREF = "Section_commands.html">Input script</A> - -<UL> 3.1 <A HREF = "Section_input_script.html#inp_1">LIGGGHTS(R)-PUBLIC input script</A> -<BR> - 3.2 <A HREF = "Section_input_script.html#inp_2">Parsing rules</A> -<BR> - 3.3 <A HREF = "Section_input_script.html#inp_3">Input script structure</A> -<BR></UL> -<LI><A HREF = "Section_commands.html">Commands</A> - - 4.1 <A HREF = "Section_commands.html#cmd_1">List of available commands </A> -<BR></UL> -<LI><A HREF = "Section_gran_models.html">Contact models</A> - - 5.1 <A HREF = "Section_gran_models.html">List of available contact models</A> -<BR></UL> -<LI><A HREF = "Section_packages.html">Packages</A> - -<UL> 6.1 <A HREF = "Section_packages.html#pkg_1">Standard packages</A> -<BR> - 6.2 <A HREF = "Section_packages.html#pkg_2">User packages</A> -<BR></UL> -<LI><A HREF = "Section_howto.html">How-to discussions</A> - -<UL> 7.1 <A HREF = "Section_howto.html#howto_1">Restarting a simulation</A> -<BR> - 7.2 <A HREF = "Section_howto.html#howto_2">2d simulations</A> -<BR> - 7.3 <A HREF = "Section_howto.html#howto_3">Running multiple simulations from one input script</A> -<BR> - 7.4 <A HREF = "Section_howto.html#howto_4">Granular models</A> -<BR> - 7.5 <A HREF = "Section_howto.html#howto_5">Coupling LIGGGHTS(R)-PUBLIC to other codes</A> -<BR> - 7.6 <A HREF = "Section_howto.html#howto_6">Visualizing LIGGGHTS(R)-PUBLIC snapshots</A> -<BR> - 7.7 <A HREF = "Section_howto.html#howto_7">Triclinic (non-orthogonal) simulation boxes</A> -<BR> - 7.8 <A HREF = "Section_howto.html#howto_8">Output from LIGGGHTS(R)-PUBLIC (thermo, dumps, computes, fixes, variables)</A> -<BR> - 7.9 <A HREF = "Section_howto.html#howto_9">Walls</A> -<BR> - 7.10 <A HREF = "#howto_10">Library interface to LIGGGHTS(R)-PUBLIC</A> -<BR></UL> -<LI><A HREF = "Section_modify.html">Modifying & extending LIGGGHTS(R)-PUBLIC</A> - -<UL> 8.1 <A HREF = "Section_modify.html#mod_1">Atom styles</A> -<BR> - 8.2 <A HREF = "Section_modify.html#mod_2">Compute styles</A> -<BR> - 8.4 <A HREF = "Section_modify.html#mod_3">Dump styles</A> -<BR> - 8.5 <A HREF = "Section_modify.html#mod_4">Dump custom output options</A> -<BR> - 8.6 <A HREF = "Section_modify.html#mod_5">Fix styles</A> -<BR> - 8.6 <A HREF = "Section_modify.html#mod_6">Input script commands</A> -<BR> - 8.7 <A HREF = "Section_modify.html#mod_7">Pairwise potentials</A> -<BR> - 8.8 <A HREF = "Section_modify.html#mod_8">Region styles</A> -<BR> - 8.9 <A HREF = "Section_modify.html#mod_9">Thermodynamic output options</A> -<BR> - 8.10 <A HREF = "Section_modify.html#mod_10">Variable options</A> -<BR> - 8.11 <A HREF = "Section_modify.html#mod_11">Submitting new features for inclusion in LIGGGHTS(R)-PUBLIC</A> -<BR></UL> -<LI><A HREF = "Section_python.html">Python interface</A> - -<UL> 9.1 <A HREF = "Section_python.html#py_1">Building LIGGGHTS(R)-PUBLIC as a shared library</A> -<BR> - 9.2 <A HREF = "Section_python.html#py_2">Installing the Python wrapper into Python</A> -<BR> - 9.3 <A HREF = "Section_python.html#py_3">Extending Python with MPI to run in parallel</A> -<BR> - 9.4 <A HREF = "Section_python.html#py_4">Testing the Python-LIGGGHTS(R)-PUBLIC interface</A> -<BR> - 9.5 <A HREF = "Section_python.html#py_5">Using LIGGGHTS(R)-PUBLIC from Python</A> -<BR> - 9.6 <A HREF = "Section_python.html#py_6">Example Python scripts that use LIGGGHTS(R)-PUBLIC</A> -<BR></UL> -<LI><A HREF = "Section_errors.html">Errors</A> - -<UL> 10.1 <A HREF = "Section_errors.html#err_1">Common problems</A> -<BR> - 10.2 <A HREF = "Section_errors.html#err_2">Reporting bugs</A> -<BR> - 10.3 <A HREF = "Section_errors.html#err_3">Error & warning messages</A> -<BR></UL> - -</OL> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</BODY> - -</HTML> +<P><!-- RST +</P> diff --git a/doc/Manual.pdf b/doc/Manual.pdf index ca3a40d64cf422d4c0bae0d3b3bd1abf2fdd9429..2f6afc39281cb6fa2fa4f5100f9d992aa647f452 100644 Binary files a/doc/Manual.pdf and b/doc/Manual.pdf differ diff --git a/doc/Manual.txt b/doc/Manual.txt index f197e394ca82fb625e2a782f79ffb401f427cd6c..9852e7538b10909c427e8bc891a9419518161c9e 100644 --- a/doc/Manual.txt +++ b/doc/Manual.txt @@ -1,3 +1,4 @@ +<!-- HTML_ONLY --> <HEAD> <TITLE>LIGGGHTS(R)-PUBLIC Users Manual</TITLE> <META NAME="docnumber" CONTENT="LIGGGHTS(R)-PUBLIC DEM simulation engine"> @@ -7,6 +8,8 @@ <BODY> +<!-- END_HTML_ONLY --> + "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c :link(liws,http://www.cfdem.com) @@ -15,7 +18,6 @@ :line -<H1></H1> :line LIGGGHTS(R)-PUBLIC Documentation, Version 3.X :c,h3 :line @@ -30,8 +32,7 @@ released by DCS Computing Gmbh, Linz, Austria, "www.dcs-computing.com"_dcs , off :line -LIGGGHTS(R)-PUBLIC is open-source, distributed under the terms of the GNU Public -License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: "www.liggghts.com"_lig | "www.cfdem.com"_cfd :h4 +LIGGGHTS(R)-PUBLIC is open-source, distributed under the terms of the GNU Public License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: "www.liggghts.com"_lig | "www.cfdem.com"_cfd :link(lig,http://www.liggghts.com) :link(cfd,http://www.cfdem.com) @@ -39,11 +40,11 @@ License, version 2 or later. LIGGGHTS(R)-PUBLIC is part of CFDEM(R)project: "www Core developer and main author: Christoph Kloss, christoph.kloss@dcs-computing.com -LIGGGHTS(R)-PUBLIC is an Open Source Discrete Element Method Particle +[LIGGGHTS(R)-PUBLIC is an Open Source Discrete Element Method Particle Simulation Software, distributed by DCS Computing GmbH, Linz, Austria. LIGGGHTS (R) and CFDEM(R) are registered trade marks of DCS Computing GmbH, the producer of the LIGGGHTS (R) software and the CFDEM(R)coupling software -See http://www.cfdem.com/terms-trademark-policy for details. :h4 +See http://www.cfdem.com/terms-trademark-policy for details.] LIGGGHTS (R) Version info: :h4 @@ -81,6 +82,33 @@ Once you are familiar with LIGGGHTS(R)-PUBLIC, you may want to bookmark "this page"_Section_commands.html#comm since it gives quick access to documentation for all LIGGGHTS(R)-PUBLIC commands. +<!-- RST + +.. toctree:: + :maxdepth: 2 + :numbered: + + Section_intro + Section_start + Section_input_script + Section_commands + Section_gran_models + Section_packages + Section_howto + Section_modify + Section_python + Section_errors + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + +END_RST --> + +<!-- HTML_ONLY --> "Introduction"_Section_intro.html :olb,l 1.1 "What is LIGGGHTS(R)-PUBLIC"_intro_1 :ulb,b 1.2 "LIGGGHTS(R)-PUBLIC features"_intro_2 :b @@ -95,7 +123,7 @@ it gives quick access to documentation for all LIGGGHTS(R)-PUBLIC commands. 2.6 "Running LIGGGHTS(R)-PUBLIC"_start_6 :b 2.7 "Command-line options"_start_7 :b 2.8 "Screen output"_start_8 :ule,b -"Input script"_Section_commands.html :l +"Input script"_Section_input_script.html :l 3.1 "LIGGGHTS(R)-PUBLIC input script"_inp_1 :ulb,b 3.2 "Parsing rules"_inp_2 :b 3.3 "Input script structure"_inp_3 :ule,b @@ -203,3 +231,5 @@ it gives quick access to documentation for all LIGGGHTS(R)-PUBLIC commands. :link(err_3,Section_errors.html#err_3) </BODY> + +<!--END_HTML_ONLY --> diff --git a/doc/Section_commands.html b/doc/Section_commands.html index 8cd89279dafb4e8423c4bc6d578c6a015388ee1c..47ccf4d6bc7e85a6da388eaadec8d523dd0565b7 100644 --- a/doc/Section_commands.html +++ b/doc/Section_commands.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_input_script.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_gran_models.html">Next Section</A> +<CENTER><A HREF = "Section_input_script.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_gran_models.html">Next Section</A> </CENTER> @@ -39,10 +39,10 @@ in the command's documentation. <TR ALIGN="center"><TD ><A HREF = "mass.html">mass</A></TD><TD ><A HREF = "neigh_modify.html">neigh_modify</A></TD><TD ><A HREF = "neighbor.html">neighbor</A></TD><TD ><A HREF = "newton.html">newton</A></TD><TD ><A HREF = "next.html">next</A></TD><TD ><A HREF = "orient.html">orient</A></TD></TR> <TR ALIGN="center"><TD ><A HREF = "origin.html">origin</A></TD><TD ><A HREF = "pair_coeff.html">pair_coeff</A></TD><TD ><A HREF = "pair_style.html">pair_style</A></TD><TD ><A HREF = "partition.html">partition</A></TD><TD ><A HREF = "print.html">print</A></TD><TD ><A HREF = "processors.html">processors</A></TD></TR> <TR ALIGN="center"><TD ><A HREF = "quit.html">quit</A></TD><TD ><A HREF = "read_data.html">read_data</A></TD><TD ><A HREF = "read_dump.html">read_dump</A></TD><TD ><A HREF = "read_restart.html">read_restart</A></TD><TD ><A HREF = "region.html">region</A></TD><TD ><A HREF = "replicate.html">replicate</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "rerun.html">rerun</A></TD><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD><TD ><A HREF = "restart.html">restart</A></TD><TD ><A HREF = "run.html">run</A></TD><TD ><A HREF = "run_style.html">run_style</A></TD><TD ><A HREF = "set.html">set</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "shell.html">shell</A></TD><TD ><A HREF = "thermo.html">thermo</A></TD><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD><TD ><A HREF = "thermo_style.html">thermo_style</A></TD><TD ><A HREF = "timestep.html">timestep</A></TD><TD ><A HREF = "uncompute.html">uncompute</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "undump.html">undump</A></TD><TD ><A HREF = "unfix.html">unfix</A></TD><TD ><A HREF = "units.html">units</A></TD><TD ><A HREF = "variable.html">variable</A></TD><TD ><A HREF = "velocity.html">velocity</A></TD><TD ><A HREF = "write_data.html">write_data</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "write_dump.html">write_dump</A></TD><TD ><A HREF = "write_restart.html">write_restart</A> +<TR ALIGN="center"><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD><TD ><A HREF = "restart.html">restart</A></TD><TD ><A HREF = "run.html">run</A></TD><TD ><A HREF = "run_style.html">run_style</A></TD><TD ><A HREF = "set.html">set</A></TD><TD ><A HREF = "shell.html">shell</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "thermo.html">thermo</A></TD><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD><TD ><A HREF = "thermo_style.html">thermo_style</A></TD><TD ><A HREF = "timestep.html">timestep</A></TD><TD ><A HREF = "uncompute.html">uncompute</A></TD><TD ><A HREF = "undump.html">undump</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "unfix.html">unfix</A></TD><TD ><A HREF = "units.html">units</A></TD><TD ><A HREF = "variable.html">variable</A></TD><TD ><A HREF = "velocity.html">velocity</A></TD><TD ><A HREF = "write_data.html">write_data</A></TD><TD ><A HREF = "write_dump.html">write_dump</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "write_restart.html">write_restart</A> </TD></TR></TABLE></DIV> <HR> @@ -103,13 +103,13 @@ of each style or click on the style itself for a full description: <TR ALIGN="center"><TD ><A HREF = "fix_nve_limit.html">nve/limit</A></TD><TD ><A HREF = "fix_nve_line.html">nve/line</A></TD><TD ><A HREF = "fix_nve_noforce.html">nve/noforce</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere</A></TD></TR> <TR ALIGN="center"><TD ><A HREF = "fix_particledistribution_discrete.html">particledistribution/discrete</A></TD><TD ><A HREF = "fix_particledistribution_discrete.html">particledistribution/discrete/massbased</A></TD><TD ><A HREF = "fix_particledistribution_discrete.html">particledistribution/discrete/numberbased</A></TD><TD ><A HREF = "fix_particletemplate_multisphere.html">particletemplate/multisphere</A></TD></TR> <TR ALIGN="center"><TD ><A HREF = "fix_particletemplate_sphere.html">particletemplate/sphere</A></TD><TD ><A HREF = "fix_planeforce.html">planeforce</A></TD><TD ><A HREF = "fix_poems.html">poems</A></TD><TD ><A HREF = "fix_print.html">print</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_property.html">property/atom</A></TD><TD ><A HREF = "fix_property_atom_tracer.html">property/atom/tracer</A></TD><TD ><A HREF = "fix_property_atom_tracer_stream.html">property/atom/tracer/stream</A></TD><TD ><A HREF = "fix_property.html">property/global</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nph</A></TD><TD ><A HREF = "fix_rigid.html">rigid/npt</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nve</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid/nvt</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small</A></TD><TD ><A HREF = "fix_setforce.html">setforce</A></TD><TD ><A HREF = "fix_sph_density_continuity.html">sph/density/continuity</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_sph_density_corr.html">sph/density/corr</A></TD><TD ><A HREF = "fix_sph_density_summation.html">sph/density/summation</A></TD><TD ><A HREF = "fix_sph_pressure.html">sph/pressure</A></TD><TD ><A HREF = "fix_spring.html">spring</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD><TD ><A HREF = "fix_store_force.html">store/force</A></TD><TD ><A HREF = "fix_store_state.html">store/state</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_viscous.html">viscous</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "fix_wall_region_sph.html">wall/region/sph</A> +<TR ALIGN="center"><TD ><A HREF = "fix_property.html">property/atom</A></TD><TD ><A HREF = "fix_property_atom_timetracer.html">property/atom/timetracer</A></TD><TD ><A HREF = "fix_property_atom_tracer.html">property/atom/tracer</A></TD><TD ><A HREF = "fix_property_atom_tracer_stream.html">property/atom/tracer/stream</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_property.html">property/global</A></TD><TD ><A HREF = "fix_rigid.html">rigid</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nph</A></TD><TD ><A HREF = "fix_rigid.html">rigid/npt</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid/nve</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nvt</A></TD><TD ><A HREF = "fix_rigid.html">rigid/small</A></TD><TD ><A HREF = "fix_setforce.html">setforce</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_sph_density_continuity.html">sph/density/continuity</A></TD><TD ><A HREF = "fix_sph_density_corr.html">sph/density/corr</A></TD><TD ><A HREF = "fix_sph_density_summation.html">sph/density/summation</A></TD><TD ><A HREF = "fix_sph_pressure.html">sph/pressure</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_spring.html">spring</A></TD><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD><TD ><A HREF = "fix_store_force.html">store/force</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_store_state.html">store/state</A></TD><TD ><A HREF = "fix_viscous.html">viscous</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD><TD ><A HREF = "fix_wall_region_sph.html">wall/region/sph</A> </TD></TR></TABLE></DIV> <H4>pair_style potentials @@ -118,8 +118,8 @@ of each style or click on the style itself for a full description: potentials. Click on the style itself for a full description: </P> <DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid/overlay</A></TD><TD ><A HREF = "pair_none.html">none</A></TD></TR> -<TR ALIGN="center"><TD ><A HREF = "pair_soft.html">soft</A></TD><TD ><A HREF = "pair_sph.html">sph</A></TD><TD ><A HREF = "pair_sph_artvisc_tenscorr.html">sph/artVisc/tensCorr</A> +<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">bubble</A></TD><TD ><A HREF = "pair_gran.html">gran</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid/overlay</A></TD></TR> +<TR ALIGN="center"><TD ><A HREF = "pair_none.html">none</A></TD><TD ><A HREF = "pair_soft.html">soft</A></TD><TD ><A HREF = "pair_sph.html">sph</A></TD><TD ><A HREF = "pair_sph_artvisc_tenscorr.html">sph/artVisc/tensCorr</A> </TD></TR></TABLE></DIV> </HTML> diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt index 0275d3cae2018f3b0297b33cd720126197faf863..f7f68324e23c5aba98aa3d9e77f9387c7530cf81 100644 --- a/doc/Section_commands.txt +++ b/doc/Section_commands.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_input_script.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_gran_models.html :c +"Previous Section"_Section_input_script.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_gran_models.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) @@ -77,7 +77,6 @@ in the command's documentation. "read_restart"_read_restart.html, "region"_region.html, "replicate"_replicate.html, -"rerun"_rerun.html, "reset_timestep"_reset_timestep.html, "restart"_restart.html, "run"_run.html, @@ -225,6 +224,7 @@ of each style or click on the style itself for a full description: "poems"_fix_poems.html, "print"_fix_print.html, "property/atom"_fix_property.html, +"property/atom/timetracer"_fix_property_atom_timetracer.html, "property/atom/tracer"_fix_property_atom_tracer.html, "property/atom/tracer/stream"_fix_property_atom_tracer_stream.html, "property/global"_fix_property.html, @@ -255,6 +255,7 @@ pair_style potentials :h4 See the "pair_style"_pair_style.html command for an overview of pair potentials. Click on the style itself for a full description: +"bubble"_pair_gran.html, "gran"_pair_gran.html, "hybrid"_pair_hybrid.html, "hybrid/overlay"_pair_hybrid.html, diff --git a/doc/Section_commands_LAMMPS.html b/doc/Section_commands_LAMMPS.html index 26c6e9e9a7e0f4e6c9281893cbbb67450825e55e..8e7318a4435eab792ad99c18392fba1b96803a83 100644 --- a/doc/Section_commands_LAMMPS.html +++ b/doc/Section_commands_LAMMPS.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_input_script.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_gran_models.html">Next Section</A> +<CENTER><A HREF = "Section_input_script.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_gran_models.html">Next Section</A> </CENTER> diff --git a/doc/Section_commands_LAMMPS.txt b/doc/Section_commands_LAMMPS.txt index 08efa2ec7488e73da753fe092826cba08a9fab48..46dd2dc14311ddd68f8a253bcdd453a97010c642 100644 --- a/doc/Section_commands_LAMMPS.txt +++ b/doc/Section_commands_LAMMPS.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_input_script.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_gran_models.html :c +"Previous Section"_Section_input_script.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_gran_models.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_errors.html b/doc/Section_errors.html index e2ba77e94af350cc44a5a53572f2bc0b78e93e02..96f4943aa5e56b59526780b67595fd927eaf850f 100644 --- a/doc/Section_errors.html +++ b/doc/Section_errors.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_python.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Manual.html">Next Section</A> +<CENTER><A HREF = "Section_python.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Manual.html">Next Section</A> </CENTER> @@ -117,28 +117,31 @@ buffering or boost the sizes of messages that can be buffered. <P>If you are confident that you have found a bug in LIGGGHTS(R)-PUBLIC, follow these steps. </P> -<P>Check the <A HREF = "http://lammps.sandia.gov/bug.html">New features and bug -fixes</A> section of the <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW +<P>Check the <A HREF = "http://www.cfdem.com/liggghtsr-version-historyhttp://www.cfdem.com/liggghtsr-version-historyhttp://www.cfdem.com/liggghtsr-version-history">New features and bug +fixes</A> section of the <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW site</A> to see if the bug has already been reported or fixed or the -<A HREF = "http://lammps.sandia.gov/unbug.html">Unfixed bug</A> to see if a fix is -pending. +<A HREF = "http://www.cfdem.com/forums/bug-reports-cfdemrcoupling-liggghtsr-and-parscale">Unfixed bug</A> +to see if a fix is pending. </P> -<P>Check the <A HREF = "http://lammps.sandia.gov/mail.html">mailing list</A> +<P>Check the <A HREF = "http://www.cfdem.com/forum">forums</A> to see if it has been discussed before. </P> -<P>If not, send an email to the mailing list describing the problem with +<P>If not, please post a bug report describing the problem with any ideas you have as to what is causing it or where in the code the problem might be. The developers will ask for more info if needed, such as an input script or data files. </P> <P>The most useful thing you can do to help us fix the bug is to isolate -the problem. Run it on the smallest number of atoms and fewest number +the problem. Run it on the smallest number of particles and fewest number of processors and with the simplest input script that reproduces the bug and try to identify what command or combination of commands is causing the problem. </P> -<P>As a last resort, you can send an email directly to the -<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>. +<P>Respectively the LAMMPS bug sections +<A HREF = "http://lammps.sandia.gov/bug.html">bug</A>, +<A HREF = "http://lammps.sandia.gov/unbug.html">unfixed bug</A> +and the <A HREF = "http://lammps.sandia.gov/mail.html">mailing list</A> + can be checked. </P> <HR> diff --git a/doc/Section_errors.txt b/doc/Section_errors.txt index 66a16087ce1861db11d91a3178f75703726ca77c..6f2937a00b491ccc43265a9f3f385f59ef3b4e31 100644 --- a/doc/Section_errors.txt +++ b/doc/Section_errors.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_python.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Manual.html :c +"Previous Section"_Section_python.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Manual.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) @@ -114,27 +114,30 @@ If you are confident that you have found a bug in LIGGGHTS(R)-PUBLIC, follow the steps. Check the "New features and bug -fixes"_http://lammps.sandia.gov/bug.html section of the "LIGGGHTS(R)-PUBLIC WWW -site"_lws to see if the bug has already been reported or fixed or the -"Unfixed bug"_http://lammps.sandia.gov/unbug.html to see if a fix is -pending. +fixes"_http://www.cfdem.com/liggghtsr-version-historyhttp://www.cfdem.com/liggghtsr-version-historyhttp://www.cfdem.com/liggghtsr-version-history section of the "LIGGGHTS(R)-PUBLIC WWW +site"_liws to see if the bug has already been reported or fixed or the +"Unfixed bug"_http://www.cfdem.com/forums/bug-reports-cfdemrcoupling-liggghtsr-and-parscale +to see if a fix is pending. -Check the "mailing list"_http://lammps.sandia.gov/mail.html +Check the "forums"_http://www.cfdem.com/forum to see if it has been discussed before. -If not, send an email to the mailing list describing the problem with +If not, please post a bug report describing the problem with any ideas you have as to what is causing it or where in the code the problem might be. The developers will ask for more info if needed, such as an input script or data files. The most useful thing you can do to help us fix the bug is to isolate -the problem. Run it on the smallest number of atoms and fewest number +the problem. Run it on the smallest number of particles and fewest number of processors and with the simplest input script that reproduces the bug and try to identify what command or combination of commands is causing the problem. -As a last resort, you can send an email directly to the -"developers"_http://lammps.sandia.gov/authors.html. +Respectively the LAMMPS bug sections +"bug"_http://lammps.sandia.gov/bug.html, +"unfixed bug"_http://lammps.sandia.gov/unbug.html +and the "mailing list"_http://lammps.sandia.gov/mail.html + can be checked. :line diff --git a/doc/Section_gran_models.html b/doc/Section_gran_models.html index 828c9a329beb1efa57abd9a8f71a9fec205819f3..915e8348595c5998db89c79d87c54df280787059 100644 --- a/doc/Section_gran_models.html +++ b/doc/Section_gran_models.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_packages.html">Next Section</A> +<CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_packages.html">Next Section</A> </CENTER> @@ -14,44 +14,4 @@ This section describes what granular models can be used along with <A HREF = "pair_gran.html">pair gran</A> and <A HREF = "fix_wall_gran.html">fix wall/gran</A> -<H4>cohesion commands -</H4> -<P>Click on the style itself for a full description: -</P> -<DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "gran_cohesion_easo_capillary_viscous.html">easo/capillary/viscous</A></TD><TD ><A HREF = "gran_cohesion_sjkr.html">sjkr</A></TD><TD ><A HREF = "gran_cohesion_sjkr2.html">sjkr2</A></TD><TD ><A HREF = "gran_cohesion_washino_capillary_viscous.html">washino/capillary/viscous</A> -</TD></TR></TABLE></DIV> - -<H4>model commands -</H4> -<P>Click on the style itself for a full description: -</P> -<DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "gran_model_hertz.html">hertz</A></TD><TD ><A HREF = "gran_model_hertz_stiffness.html">hertz/stiffness</A></TD><TD ><A HREF = "gran_model_hooke.html">hooke</A></TD><TD ><A HREF = "gran_model_hooke_stiffness.html">hooke/stiffness</A> -</TD></TR></TABLE></DIV> - -<H4>rolling_friction commands -</H4> -<P>Click on the style itself for a full description: -</P> -<DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "gran_rolling_friction_cdt.html">cdt</A></TD><TD ><A HREF = "gran_rolling_friction_epsd.html">epsd</A></TD><TD ><A HREF = "gran_rolling_friction_epsd2.html">epsd2</A></TD><TD ><A HREF = "gran_rolling_friction_epsd3.html">epsd3</A> -</TD></TR></TABLE></DIV> - -<H4>surface commands -</H4> -<P>Click on the style itself for a full description: -</P> -<DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "gran_surface_sphere.html">sphere</A> -</TD></TR></TABLE></DIV> - -<H4>tangential commands -</H4> -<P>Click on the style itself for a full description: -</P> -<DIV ALIGN=center><TABLE BORDER=1 > -<TR ALIGN="center"><TD ><A HREF = "gran_tangential_history.html">history</A></TD><TD ><A HREF = "gran_tangential_no_history.html">no_history</A> -</TD></TR></TABLE></DIV> - </HTML> diff --git a/doc/Section_gran_models.txt b/doc/Section_gran_models.txt index 66c2dc58f17ca21e8e85e3dd71a2ba6961bb7e21..5db40d11a5c5024916049ee0a9d83dc2cdd07762 100644 --- a/doc/Section_gran_models.txt +++ b/doc/Section_gran_models.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_commands.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_packages.html :c +"Previous Section"_Section_commands.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_packages.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) @@ -13,43 +13,3 @@ This section describes what granular models can be used along with -cohesion commands :h4 - -Click on the style itself for a full description: - -"easo/capillary/viscous"_gran_cohesion_easo_capillary_viscous.html, -"sjkr"_gran_cohesion_sjkr.html, -"sjkr2"_gran_cohesion_sjkr2.html, -"washino/capillary/viscous"_gran_cohesion_washino_capillary_viscous.html :tb(c=4,ea=c) - -model commands :h4 - -Click on the style itself for a full description: - -"hertz"_gran_model_hertz.html, -"hertz/stiffness"_gran_model_hertz_stiffness.html, -"hooke"_gran_model_hooke.html, -"hooke/stiffness"_gran_model_hooke_stiffness.html :tb(c=4,ea=c) - -rolling_friction commands :h4 - -Click on the style itself for a full description: - -"cdt"_gran_rolling_friction_cdt.html, -"epsd"_gran_rolling_friction_epsd.html, -"epsd2"_gran_rolling_friction_epsd2.html, -"epsd3"_gran_rolling_friction_epsd3.html :tb(c=4,ea=c) - -surface commands :h4 - -Click on the style itself for a full description: - -"sphere"_gran_surface_sphere.html :tb(c=4,ea=c) - -tangential commands :h4 - -Click on the style itself for a full description: - -"history"_gran_tangential_history.html, -"no_history"_gran_tangential_no_history.html :tb(c=4,ea=c) - diff --git a/doc/Section_gran_models_prev.html b/doc/Section_gran_models_prev.html index 7c9b56168e7d933dac804df01ba296963e9d4f81..8f621927824dac1d33297886aa500ed83756b221 100644 --- a/doc/Section_gran_models_prev.html +++ b/doc/Section_gran_models_prev.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_packages.html">Next Section</A> +<CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_packages.html">Next Section</A> </CENTER> diff --git a/doc/Section_gran_models_prev.txt b/doc/Section_gran_models_prev.txt index 11cb93afd1a5114dffaf3039dca8697483a59c1b..43971db1dc4575a1598fc4bfc8d6dcdc1f218a81 100644 --- a/doc/Section_gran_models_prev.txt +++ b/doc/Section_gran_models_prev.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_commands.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_packages.html :c +"Previous Section"_Section_commands.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_packages.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_howto.html b/doc/Section_howto.html index aeb6a61b21bc1c2b5b346c0325800279a8ea4669..2dfa9f2eedd11561e80581df4185cc1e7351e467 100644 --- a/doc/Section_howto.html +++ b/doc/Section_howto.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_packages.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_modify.html">Next Section</A> +<CENTER><A HREF = "Section_packages.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_modify.html">Next Section</A> </CENTER> diff --git a/doc/Section_howto.txt b/doc/Section_howto.txt index 0515f725a17f335659351dcc334e9a4a30d4a839..1443ef93d110a00067f34009bdb37d0ecd00ea48 100644 --- a/doc/Section_howto.txt +++ b/doc/Section_howto.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_packages.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_modify.html :c +"Previous Section"_Section_packages.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_modify.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_input_script.html b/doc/Section_input_script.html index 47e8cb70aebaf3a8184bb3fb371c18ab6ac42923..753e7f32002bc2c89d9582f9dd3bdef17f687737 100644 --- a/doc/Section_input_script.html +++ b/doc/Section_input_script.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_start.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_commands.html">Next Section</A> +<CENTER><A HREF = "Section_start.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_commands.html">Next Section</A> </CENTER> @@ -9,7 +9,7 @@ <HR> -<H3>3. Commands +<H3>3. Input Script </H3> <P>This section describes how a LIGGGHTS(R)-PUBLIC input script is formatted and the input script commands used to define a LIGGGHTS(R)-PUBLIC simulation. @@ -173,7 +173,7 @@ allowed, but that should be sufficient for most use cases. <P>This section describes the structure of a typical LIGGGHTS(R)-PUBLIC input script. The "examples" directory in the LIGGGHTS(R)-PUBLIC distribution contains many sample input scripts; the corresponding problems are discussed in -<A HREF = "Section_example.html">Section_example</A>, and animated on the <A HREF = "lws">LIGGGHTS(R)-PUBLIC +<A HREF = "Section_example.html">Section_example</A>, and animated on the <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A>. </P> <P>A LIGGGHTS(R)-PUBLIC input script typically has 4 parts: diff --git a/doc/Section_input_script.txt b/doc/Section_input_script.txt index 3a1811d7821fdb8bf4ad7e5319cda4f7b582a89f..330c3a7ea99cc42eadc719cd529eccc40db1bc09 100644 --- a/doc/Section_input_script.txt +++ b/doc/Section_input_script.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_start.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_commands.html :c +"Previous Section"_Section_start.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_commands.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) @@ -6,7 +6,7 @@ :line -3. Commands :h3 +3. Input Script :h3 This section describes how a LIGGGHTS(R)-PUBLIC input script is formatted and the input script commands used to define a LIGGGHTS(R)-PUBLIC simulation. @@ -170,7 +170,7 @@ This section describes the structure of a typical LIGGGHTS(R)-PUBLIC input scrip The "examples" directory in the LIGGGHTS(R)-PUBLIC distribution contains many sample input scripts; the corresponding problems are discussed in "Section_example"_Section_example.html, and animated on the "LIGGGHTS(R)-PUBLIC -WWW Site"_lws. +WWW Site"_liws. A LIGGGHTS(R)-PUBLIC input script typically has 4 parts: diff --git a/doc/Section_intro.html b/doc/Section_intro.html index 5ed97cd36ef4fa5d4bf29b43fa5650e29b426eae..4e6f92379cb756e4697ce83414e0bd6e19235882 100644 --- a/doc/Section_intro.html +++ b/doc/Section_intro.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Manual.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_start.html">Next Section</A> +<CENTER><A HREF = "Manual.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_start.html">Next Section</A> </CENTER> diff --git a/doc/Section_intro.txt b/doc/Section_intro.txt index eda531ed0857528c8c8cbb71c9d0c20ba2f0001f..58d0187ea649a66feebc141474fed9715c5d7508 100644 --- a/doc/Section_intro.txt +++ b/doc/Section_intro.txt @@ -1,4 +1,4 @@ -"Previous Section"_Manual.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_start.html :c +"Previous Section"_Manual.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_start.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_modify.html b/doc/Section_modify.html index 0d49b361c74e786604a6446e1be02b23e68fa37d..39f7202f74451060dd625f4b4de98225a9af88a8 100644 --- a/doc/Section_modify.html +++ b/doc/Section_modify.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_howto.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_python.html">Next Section</A> +<CENTER><A HREF = "Section_howto.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_python.html">Next Section</A> </CENTER> diff --git a/doc/Section_modify.txt b/doc/Section_modify.txt index edca49ea7e38173eac1e208a9c7abc9d2a9d7825..ebbfd6cc3fd0d16c8f4c8aaa9033a84d3695e7ba 100644 --- a/doc/Section_modify.txt +++ b/doc/Section_modify.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_howto.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_python.html :c +"Previous Section"_Section_howto.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_python.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_packages.html b/doc/Section_packages.html index 3135172e0ca101479ea699b65baae3c4a0aa80b8..b8f63387e7d058fd141ec17fd030ac16ada04b32 100644 --- a/doc/Section_packages.html +++ b/doc/Section_packages.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_gran_models.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_howto.html">Next Section</A> +<CENTER><A HREF = "Section_gran_models.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_howto.html">Next Section</A> </CENTER> diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt index 74590619b4a3a070d8fd4961ff41dcdc27f4f9f2..6d55b25ae5f4e250de0f91a4280303df02dc2092 100644 --- a/doc/Section_packages.txt +++ b/doc/Section_packages.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_gran_models.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_howto.html :c +"Previous Section"_Section_gran_models.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_howto.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_python.html b/doc/Section_python.html index 279d9acb3a4d625b9f182046f70a9a9f4bb0b10a..c63ca0bc4cb2de1914f4c150021936c81f716be4 100644 --- a/doc/Section_python.html +++ b/doc/Section_python.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_modify.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_errors.html">Next Section</A> +<CENTER><A HREF = "Section_modify.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_errors.html">Next Section</A> </CENTER> diff --git a/doc/Section_python.txt b/doc/Section_python.txt index 7d60b938ca4e0cf9b0202361d19d14f7fa857139..22fab4acec6598d1fc2122ddeb2a06c83234a537 100644 --- a/doc/Section_python.txt +++ b/doc/Section_python.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_modify.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_errors.html :c +"Previous Section"_Section_modify.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_errors.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/Section_start.html b/doc/Section_start.html index 7236280bc8bdd76d2880b8f16694f697831398e1..516ca94781ea62113a7c27972c70e57fd8081443 100644 --- a/doc/Section_start.html +++ b/doc/Section_start.html @@ -1,5 +1,5 @@ <HTML> -<CENTER><A HREF = "Section_intro.html">Previous Section</A> - <A HREF = "lws">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_input_script.html">Next Section</A> +<CENTER><A HREF = "Section_intro.html">Previous Section</A> - <A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> - <A HREF = "Section_input_script.html">Next Section</A> </CENTER> diff --git a/doc/Section_start.txt b/doc/Section_start.txt index 05762f27a872cbb96dccec55c51d853eb5688d9b..4daa8167816a8f843ad2838bd8ffbf534a1f3e5b 100644 --- a/doc/Section_start.txt +++ b/doc/Section_start.txt @@ -1,4 +1,4 @@ -"Previous Section"_Section_intro.html - "LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_input_script.html :c +"Previous Section"_Section_intro.html - "LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc - "Next Section"_Section_input_script.html :c :link(liws,http://www.cfdem.com) :link(ld,Manual.html) diff --git a/doc/atom_modify.html b/doc/atom_modify.html index d7c6ccb3983dd81c415e505853648af9d87946af..703017ee4f08fdec8ed220c75ed3039dfe8dbc19 100644 --- a/doc/atom_modify.html +++ b/doc/atom_modify.html @@ -66,20 +66,20 @@ turns off the <I>first</I> option. </P> <P>It is OK to use the <I>first</I> keyword with a group that has not yet been defined, e.g. to use the atom_modify first command at the beginning of -your input script. LIGGGHTS(R)-PUBLIC does not use the group until a simullation +your input script. LIGGGHTS(R)-PUBLIC does not use the group until a simulation is run. </P> <P>The <I>sort</I> keyword turns on a spatial sorting or reordering of atoms within each processor's sub-domain every <I>Nfreq</I> timesteps. If <I>Nfreq</I> is set to 0, then sorting is turned off. Sorting can improve cache performance and thus speed-up a LIGGGHTS(R)-PUBLIC simulation, as discussed -in a paper by <A HREF = "#Meloni">(Meloni)</A>. Its efficacy depends on the problem +in a paper by <A HREF = "#Meloni">(Meloni)</A>. Its efficiency depends on the problem size (atoms/processor), how quickly the system becomes disordered, and various other factors. As a general rule, sorting is typically more effective at speeding up simulations of liquids as opposed to solids. In tests we have done, the speed-up can range from zero to 3-4x. </P> -<P>Reordering is peformed every <I>Nfreq</I> timesteps during a dynamics run +<P>Reordering is performed every <I>Nfreq</I> timesteps during a dynamics run or iterations during a minimization. More precisely, reordering occurs at the first reneighboring that occurs after the target timestep. The reordering is performed locally by each processor, diff --git a/doc/atom_modify.txt b/doc/atom_modify.txt index 59d6388202dcacc0b2cc4ec278d8e4bf18d37dfa..76ad545513547650b7432b81fb5469c66834cbbd 100644 --- a/doc/atom_modify.txt +++ b/doc/atom_modify.txt @@ -60,20 +60,20 @@ turns off the {first} option. It is OK to use the {first} keyword with a group that has not yet been defined, e.g. to use the atom_modify first command at the beginning of -your input script. LIGGGHTS(R)-PUBLIC does not use the group until a simullation +your input script. LIGGGHTS(R)-PUBLIC does not use the group until a simulation is run. The {sort} keyword turns on a spatial sorting or reordering of atoms within each processor's sub-domain every {Nfreq} timesteps. If {Nfreq} is set to 0, then sorting is turned off. Sorting can improve cache performance and thus speed-up a LIGGGHTS(R)-PUBLIC simulation, as discussed -in a paper by "(Meloni)"_#Meloni. Its efficacy depends on the problem +in a paper by "(Meloni)"_#Meloni. Its efficiency depends on the problem size (atoms/processor), how quickly the system becomes disordered, and various other factors. As a general rule, sorting is typically more effective at speeding up simulations of liquids as opposed to solids. In tests we have done, the speed-up can range from zero to 3-4x. -Reordering is peformed every {Nfreq} timesteps during a dynamics run +Reordering is performed every {Nfreq} timesteps during a dynamics run or iterations during a minimization. More precisely, reordering occurs at the first reneighboring that occurs after the target timestep. The reordering is performed locally by each processor, diff --git a/doc/compute_coord_gran.txt b/doc/compute_coord_gran.txt index f8aaa6f270898f7cc447698aa4d19e3577c1c83d..91a7b92de875dc33c289fd8bf6637bb04096d59d 100644 --- a/doc/compute_coord_gran.txt +++ b/doc/compute_coord_gran.txt @@ -1,6 +1,6 @@ -"LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c +"LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c -:link(lws,http://www.cfdem.com) +:link(liws,http://www.cfdem.com) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) diff --git a/doc/compute_pair_gran_local.txt b/doc/compute_pair_gran_local.txt index c8322ce090224d6854b9642bad1e6d27238cbe59..68b2ff7c9a239544633cd82877337daa79db7305 100644 --- a/doc/compute_pair_gran_local.txt +++ b/doc/compute_pair_gran_local.txt @@ -1,6 +1,6 @@ -"LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c +"LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c -:link(lws,http://www.cfdem.com) +:link(liws,http://www.cfdem.com) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) diff --git a/doc/compute_rigid.txt b/doc/compute_rigid.txt index 55795d34132593cffb5ad5613f2c213a7ebc4900..7e88275ca62661826b775c95ab6e01bec6a19ee4 100644 --- a/doc/compute_rigid.txt +++ b/doc/compute_rigid.txt @@ -1,6 +1,6 @@ -"LIGGGHTS(R)-PUBLIC WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c +"LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c -:link(lws,http://www.cfdem.com) +:link(liws,http://www.cfdem.com) :link(ld,Manual.html) :link(lc,Section_commands.html#comm) diff --git a/doc/dump.html b/doc/dump.html index 54cae4bb5fa6839cb9c98d50c926dca91882228d..0cf8071e924b95b26bdcd7dbcdda84714e2540cd 100644 --- a/doc/dump.html +++ b/doc/dump.html @@ -286,8 +286,8 @@ all meshes used in the simulation are dumped. </P> <P>The <I>mesh/vtk</I> style can be used to dump active mesh geometries defined via <A HREF = "fix_mesh.html">fix mesh</A> commands to a series of VTK files. -Different keywords can be used to dump the per-triangle stress (force -magnitude / element area), id, velocity, wear, stress components +Different keywords can be used to dump the per-triangle averaged stress +in normal and shear direction, id, velocity, wear, stress components (fx / element area, fy / element area, fz / element area), area (area of each element) or the process which owns the element (visulatisation of the parallel decomposition) into the specified file using a diff --git a/doc/dump.txt b/doc/dump.txt index 73611f4c438501a95302edac386eca313da828c2..c14e0a1ad90fb64d969822c11688254881915678 100644 --- a/doc/dump.txt +++ b/doc/dump.txt @@ -274,8 +274,8 @@ all meshes used in the simulation are dumped. The {mesh/vtk} style can be used to dump active mesh geometries defined via "fix mesh"_fix_mesh.html commands to a series of VTK files. -Different keywords can be used to dump the per-triangle stress (force -magnitude / element area), id, velocity, wear, stress components +Different keywords can be used to dump the per-triangle averaged stress +in normal and shear direction, id, velocity, wear, stress components (fx / element area, fy / element area, fz / element area), area (area of each element) or the process which owns the element (visulatisation of the parallel decomposition) into the specified file using a diff --git a/doc/fix_insert_pack.html b/doc/fix_insert_pack.html index 90513fb4fbcdd0f2cab99662f8d9d9e2fc360a1c..b4881272d7a21f3c62d25f410a13173113b4546d 100644 --- a/doc/fix_insert_pack.html +++ b/doc/fix_insert_pack.html @@ -29,7 +29,7 @@ <LI>one or more general keyword/value pairs can be appended -<LI>general_keywords = <I>verbose</I> or <I>maxattempt</I> or <I>insert_every</I> or <I>overlapcheck</I> or <I>all_in</I> or <I>random_distribute</I> or <I>vel constant</I> or <I>vel uniform</I> or <I>vel gaussian</I> or <I>orientation</I> or <I>omega</I> or <I>set_property</I> +<LI>general_keywords = <I>verbose</I> or <I>maxattempt</I> or <I>insert_every</I> or <I>overlapcheck</I> or <I>all_in</I> or <I>random_distribute</I> or <I>compress_tags</I> or <I>vel constant</I> or <I>vel uniform</I> or <I>vel gaussian</I> or <I>orientation</I> or <I>omega</I> or <I>set_property</I> <PRE> <I>verbose</I> = yes or no <I>maxattempt</I> value = ma @@ -42,6 +42,7 @@ <I>overlapcheck</I> value = yes or no <I>all_in</I> value = yes or no <I>random_distribute</I> value = exact or uncorrelated + <I>compress_tags</I> value = yes or no <I>vel constant</I> values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -165,6 +166,15 @@ the <I>random_distribute</I> settings. This is because in this case the and applying a simple floor/ceil rounding operation would lead to a statistical bias. </P> +<P>If keyword <I>compress_tags</I> is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. +</P> +<P>IMPORTANT NOTE: Setting <I>compress_tags</I> to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. +</P> <P>The initial velocity and rotational velocity can be controlled via the <I>vel</I> and <I>omega</I> keywords. <I>vel constant</I> simply patches a constant velocity to the inserted particles, <I>vel uniform</I> sets uniformly distributed @@ -235,6 +245,7 @@ is a tet mesh region. </P> <P>The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, ntry_mc = 100000, random_distribute = exact +duration = insert_every, ntry_mc = 100000, random_distribute = exact, +<I>compress_tags</I> = no </P> </HTML> diff --git a/doc/fix_insert_pack.txt b/doc/fix_insert_pack.txt index f8225721314790d40fb62a695cf4caffb2d9c44e..62d8c52e7dca12fcd31a4d43f9495aae43085f5d 100644 --- a/doc/fix_insert_pack.txt +++ b/doc/fix_insert_pack.txt @@ -19,7 +19,7 @@ seed_value = random # seed (positive integer) :l distributiontemplate = obligatory keyword :l dist-ID = ID of a "fix_particledistribution_discrete"_fix_particledistribution_discrete.html to be used for particle insertion :l one or more general keyword/value pairs can be appended :l -general_keywords = {verbose} or {maxattempt} or {insert_every} or {overlapcheck} or {all_in} or {random_distribute} or {vel constant} or {vel uniform} or {vel gaussian} or {orientation} or {omega} or {set_property} :l +general_keywords = {verbose} or {maxattempt} or {insert_every} or {overlapcheck} or {all_in} or {random_distribute} or {compress_tags} or {vel constant} or {vel uniform} or {vel gaussian} or {orientation} or {omega} or {set_property} :l {verbose} = yes or no {maxattempt} value = ma ma = max # of insertion attempts per atom (positive integer) @@ -31,6 +31,7 @@ general_keywords = {verbose} or {maxattempt} or {insert_every} or {overlapcheck} {overlapcheck} value = yes or no {all_in} value = yes or no {random_distribute} value = exact or uncorrelated + {compress_tags} value = yes or no {vel constant} values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -151,6 +152,15 @@ the {random_distribute} settings. This is because in this case the and applying a simple floor/ceil rounding operation would lead to a statistical bias. +If keyword {compress_tags} is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. + +IMPORTANT NOTE: Setting {compress_tags} to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. + The initial velocity and rotational velocity can be controlled via the {vel} and {omega} keywords. {vel constant} simply patches a constant velocity to the inserted particles, {vel uniform} sets uniformly distributed @@ -221,5 +231,6 @@ Dynamic regions are not supported as insertion region. The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, ntry_mc = 100000, random_distribute = exact +duration = insert_every, ntry_mc = 100000, random_distribute = exact, +{compress_tags} = no diff --git a/doc/fix_insert_rate_region.html b/doc/fix_insert_rate_region.html index d9259398aa8c08adad54a27c80f51fbb4af46186..8dc1708b16289e8e7829e9b6a9714d458de80a9c 100644 --- a/doc/fix_insert_rate_region.html +++ b/doc/fix_insert_rate_region.html @@ -29,7 +29,7 @@ <LI>one or more general keyword/value pairs can be appended -<LI>general_keywords = <I>verbose</I> or <I>maxattampt</I> or <I>nparticles</I> or <I>mass</I> or <I>particlerate</I> or <I>massrate</I> or <I>insert_every</I> or <I>overlapcheck</I> or <I>all_in</I> or <I>random_distribute</I> or <I>vel constant</I> or <I>vel uniform</I> or <I>vel gaussian</I> or <I>orientation</I> or <I>omega</I> or <I>set_property</I> +<LI>general_keywords = <I>verbose</I> or <I>maxattampt</I> or <I>nparticles</I> or <I>mass</I> or <I>particlerate</I> or <I>massrate</I> or <I>insert_every</I> or <I>overlapcheck</I> or <I>all_in</I> or <I>random_distribute</I> or <I>compress_tags</I> or <I>vel constant</I> or <I>vel uniform</I> or <I>vel gaussian</I> or <I>orientation</I> or <I>omega</I> or <I>set_property</I> <PRE> <I>verbose</I> = yes or no <I>maxattempt</I> value = ma @@ -52,6 +52,7 @@ <I>overlapcheck</I> value = yes or no <I>all_in</I> value = yes or no <I>random_distribute</I> value = exact or uncorrelated + <I>compress_tags</I> value = yes or no <I>vel constant</I> values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -79,7 +80,7 @@ omegay = y-comonent of angular velocity (1/time units) omegaz = z-comonent of angular velocity (1/time units) <I>set_property</I> values = property-ID val - property-ID = ID of a <A HREF = "fix_property.html">fix property/atom</A> holding a scalar value for each particle + property-variablename = variable name of a <A HREF = "fix_property.html">fix property/atom</A> holding a scalar value for each particle val = value to initialize the property with upon insertion </PRE> <LI>following the general keyword/value section, one or more rate_region keyword/value pairs can be appended for the fix insert/rate/region command @@ -173,6 +174,15 @@ the <I>random_distribute</I> settings. This is because in this case the and applying a simple floor/ceil rounding operation would lead to a statistical bias. </P> +<P>If keyword <I>compress_tags</I> is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. +</P> +<P>IMPORTANT NOTE: Setting <I>compress_tags</I> to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. +</P> <P>The initial velocity and rotational velocity can be controlled via the <I>vel</I> and <I>omega</I> keywords. <I>vel constant</I> simply patches a constant velocity to the inserted particles, <I>vel uniform</I> sets uniformly distributed @@ -223,6 +233,7 @@ is a tet mesh region. </P> <P>The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, ntry_mc = 100000, random_distribute = exact +duration = insert_every, ntry_mc = 100000, random_distribute = exact, +<I>compress_tags</I> = no </P> </HTML> diff --git a/doc/fix_insert_rate_region.txt b/doc/fix_insert_rate_region.txt index 357e31b25b3f0a3903eb81a58aed34cee390dcee..4cc3fe5fbd804372783df4e4a3fdd957fd2fd393 100644 --- a/doc/fix_insert_rate_region.txt +++ b/doc/fix_insert_rate_region.txt @@ -19,7 +19,7 @@ seed_value = random # seed (positive integer) :l distributiontemplate = obligatory keyword :l dist-ID = ID of a "fix_particledistribution_discrete"_fix_particledistribution_discrete.html to be used for particle insertion :l one or more general keyword/value pairs can be appended :l -general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {particlerate} or {massrate} or {insert_every} or {overlapcheck} or {all_in} or {random_distribute} or {vel constant} or {vel uniform} or {vel gaussian} or {orientation} or {omega} or {set_property} :l +general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {particlerate} or {massrate} or {insert_every} or {overlapcheck} or {all_in} or {random_distribute} or {compress_tags} or {vel constant} or {vel uniform} or {vel gaussian} or {orientation} or {omega} or {set_property} :l {verbose} = yes or no {maxattempt} value = ma ma = max # of insertion attempts per atom (positive integer) @@ -41,6 +41,7 @@ general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {parti {overlapcheck} value = yes or no {all_in} value = yes or no {random_distribute} value = exact or uncorrelated + {compress_tags} value = yes or no {vel constant} values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -68,7 +69,7 @@ general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {parti omegay = y-comonent of angular velocity (1/time units) omegaz = z-comonent of angular velocity (1/time units) {set_property} values = property-ID val - property-ID = ID of a "fix property/atom"_fix_property.html holding a scalar value for each particle + property-variablename = variable name of a "fix property/atom"_fix_property.html holding a scalar value for each particle val = value to initialize the property with upon insertion :pre following the general keyword/value section, one or more rate_region keyword/value pairs can be appended for the fix insert/rate/region command :l @@ -160,6 +161,15 @@ the {random_distribute} settings. This is because in this case the and applying a simple floor/ceil rounding operation would lead to a statistical bias. +If keyword {compress_tags} is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. + +IMPORTANT NOTE: Setting {compress_tags} to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. + The initial velocity and rotational velocity can be controlled via the {vel} and {omega} keywords. {vel constant} simply patches a constant velocity to the inserted particles, {vel uniform} sets uniformly distributed @@ -210,4 +220,5 @@ Dynamic regions are not supported as insertion region. The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, ntry_mc = 100000, random_distribute = exact +duration = insert_every, ntry_mc = 100000, random_distribute = exact, +{compress_tags} = no diff --git a/doc/fix_insert_stream.html b/doc/fix_insert_stream.html index d0b8d5ac64d3381d6372733056723a2a4d6af99e..24835373bfc09e40b9d2717afff79f8e3fc25a0f 100644 --- a/doc/fix_insert_stream.html +++ b/doc/fix_insert_stream.html @@ -51,6 +51,7 @@ <I>overlapcheck</I> value = yes or no <I>all_in</I> value = yes or no <I>random_distribute</I> value = exact or uncorrelated + <I>compress_tags</I> value = yes or no <I>vel constant</I> values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -78,7 +79,7 @@ omegay = y-comonent of angular velocity (1/time units) omegaz = z-comonent of angular velocity (1/time units) <I>set_property</I> values = property-ID val - property-ID = ID of a <A HREF = "fix_property.html">fix property/atom</A> holding a scalar value for each particle + property-variablename = variable name of a <A HREF = "fix_property.html">fix property/atom</A> holding a scalar value for each particle val = value to initialize the property with upon insertion </PRE> <LI>following the general keyword/value section, one or more stream keyword/value pairs can be appended for the fix insert/stream command @@ -228,6 +229,15 @@ processes, this can lead to a speed-up of insertion as random number generation is more efficient. For cases where the extrusion volume is divided among few processes this will impose a small computation overhead. </P> +<P>If keyword <I>compress_tags</I> is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. +</P> +<P>IMPORTANT NOTE: Setting <I>compress_tags</I> to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. +</P> <P>The initial velocity and rotational velocity can be controlled via the <I>vel</I> and <I>omega</I> keywords. <I>vel constant</I> simply patches a constant velocity to the inserted particles, <I>vel uniform</I> sets uniformly distributed @@ -239,6 +249,14 @@ The insertion velocity must be non-zero. properties such as temperatures, which are stored in a a <A HREF = "fix_property.html">fix property/atom</A>. </P> +<P>The setting of <I>compress_tags</I> will trigger a periodic re-tagging of +atom ids. This is usefull in case the simulation domain is used to +model a periodic in and outflow of particles. If this switch is set, +the global ids of the particles will remain in a certain range, +and no "holes" in the arrays holding the global atom ids exist. +IMPORTANT NOTE: This functionality may confuse external tools which +perform post-processing based on atom IDs! +</P> <P><B>Restart, fix_modify, output, run start/stop, minimize info:</B> </P> <P>Information about this fix is written to <A HREF = "restart.html">binary restart @@ -268,6 +286,7 @@ The insertion face cannot move. </P> <P>The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, random_distribute = exact, parallel = no +duration = insert_every, random_distribute = exact, parallel = no, +<I>compress_tags</I> = no </P> </HTML> diff --git a/doc/fix_insert_stream.txt b/doc/fix_insert_stream.txt index 18bdb4ba01f6c8ef25c24aaaccfcc01d72ad7f38..8c538e4c2fedd700dac86651019fca82e80d86fb 100644 --- a/doc/fix_insert_stream.txt +++ b/doc/fix_insert_stream.txt @@ -39,6 +39,7 @@ general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {parti {overlapcheck} value = yes or no {all_in} value = yes or no {random_distribute} value = exact or uncorrelated + {compress_tags} value = yes or no {vel constant} values = vx vy vz vx = x-velocity at insertion (velocity units) vy = y-velocity at insertion (velocity units) @@ -66,7 +67,7 @@ general_keywords = {verbose} or {maxattampt} or {nparticles} or {mass} or {parti omegay = y-comonent of angular velocity (1/time units) omegaz = z-comonent of angular velocity (1/time units) {set_property} values = property-ID val - property-ID = ID of a "fix property/atom"_fix_property.html holding a scalar value for each particle + property-variablename = variable name of a "fix property/atom"_fix_property.html holding a scalar value for each particle val = value to initialize the property with upon insertion :pre following the general keyword/value section, one or more stream keyword/value pairs can be appended for the fix insert/stream command :l @@ -213,6 +214,15 @@ processes, this can lead to a speed-up of insertion as random number generation is more efficient. For cases where the extrusion volume is divided among few processes this will impose a small computation overhead. +If keyword {compress_tags} is set to 'yes', then atom IDs are re-assigned +after each insertion procedure. The default is 'no'. This is typically +only recommended if some models internally store arrays which have the +length defined via the max ID of any atom. + +IMPORTANT NOTE: Setting {compress_tags} to 'yes' will result in all contact +history to be lost at that point in time. External post-processing tools +will give wrong results because they typically track atoms via their IDs. + The initial velocity and rotational velocity can be controlled via the {vel} and {omega} keywords. {vel constant} simply patches a constant velocity to the inserted particles, {vel uniform} sets uniformly distributed @@ -224,6 +234,14 @@ The {set_property} option can be used to initialize scalar per-particle properties such as temperatures, which are stored in a a "fix property/atom"_fix_property.html. +The setting of {compress_tags} will trigger a periodic re-tagging of +atom ids. This is usefull in case the simulation domain is used to +model a periodic in and outflow of particles. If this switch is set, +the global ids of the particles will remain in a certain range, +and no "holes" in the arrays holding the global atom ids exist. +IMPORTANT NOTE: This functionality may confuse external tools which +perform post-processing based on atom IDs! + [Restart, fix_modify, output, run start/stop, minimize info:] Information about this fix is written to "binary restart @@ -253,4 +271,5 @@ The insertion face cannot move. The defaults are maxattempt = 50, all_in = no, overlapcheck = yes vel = 0.0 0.0 0.0, omega = 0.0 0.0 0.0, start = next time-step, -duration = insert_every, random_distribute = exact, parallel = no +duration = insert_every, random_distribute = exact, parallel = no, +{compress_tags} = no diff --git a/doc/fix_mesh_surface.html b/doc/fix_mesh_surface.html index 2afbc37bc82aa3e60e0740277d36fea4a505c121..2809edc9362169e19f947abd1f19a25681d41ffc 100644 --- a/doc/fix_mesh_surface.html +++ b/doc/fix_mesh_surface.html @@ -28,11 +28,13 @@ fix ID group-ID mesh/surface/planar file filename premesh_keywords premesh_value <LI>zero or more premesh_keywords/premesh_value pairs may be appended -<LI>premesh_keyword = <I>type</I> or <I>precision</I> or <I>heal</I> or <I>element_exclusion_list</I> or <I>verbose</I> +<LI>premesh_keyword = <I>type</I> or <I>precision</I> or <I>heal</I> or <I>min_feature_length</I> or <I>element_exclusion_list</I> or <I>verbose</I> <PRE> <I>type</I> value = atom type (material type) of the wall imported from the STL file + <I>region</I> value = ID of <A HREF = "region.html">region</A> to filter elements which are imported <I>precision</I> value = length mesh nodes this far away at maximum will be recognized as identical (length units) <I>heal</I> value = auto_remove_duplicates or no + <I>min_feature_length</I> value = exclude element if belongs to an entity where no element is larger than this (length units) <I>element_exclusion_list</I> values = mode element_exlusion_file mode = read or write element_exlusion_file = name of file containing the elements to be excluded @@ -50,6 +52,7 @@ fix ID group-ID mesh/surface/planar file filename premesh_keywords premesh_value axis = obligatory keyword ax, ay, az = axis vector for rotation (length units) angle = obligatory keyword + ang = rotation angle (degrees) <I>temperature</I> value = T0 T0 = Temperature of the wall (temperature units) <I>mass_temperature</I> value = mt0 @@ -86,9 +89,15 @@ ASCII STL files or legacy ASCII VTK files. Style <I>mesh/surface</I> is a genera <I>mesh/surface/planar</I> represents a planar mesh. <I>mesh/surface/planar</I> requires the mesh to consist of only 1 planar face. </P> +<P>The <I>region</I> keyword can be used to filter the elements which are imported. An element is only +imported if all of its vertices is inside the specified <A HREF = "region.html">region</A>. Please note that +the geometric extent of this <A HREF = "region.html">region</A> refer to the unscaled, unmoved, and unrotated +original state of the geometry. +</P> <P>Generall, you can apply scaling, offset and rotation to the imported mesh via keywords <I>scale</I>, -<I>move</I>, <I>rotate</I>. Operations are applied in the order as they are specified. The group-ID defines -which particles will "see" the mesh, in case it is used as a granular wall. +<I>move</I>, <I>rotate</I>. Operations are applied in the order as they are specified. The rotation via <I>rotate</I> is performed around the rotation axis that goes through the origin (0,0,0) and in the direction of <I>axis</I>. +</P> +<P>The group-ID defines which particles will "see" the mesh, in case it is used as a granular wall. </P> <P>One fix represents one wall with a specific material, where the material is identified via keyword <I>type</I>. If multiple meshes with different materials are desired, the respective @@ -124,7 +133,7 @@ to give you as much information about the issue as possible. </P> <LI>The <I>curvature</I> must not be larger than any angle in any mesh element -<LI>There must be no element with an angle < 0.181185 degrees in any element (hard limit for angles) +<LI>There must be no element with an angle < 0.0181185 degrees in any element (hard limit for angles) <LI>The number of neighbor elements must be <= 5 for any element @@ -152,6 +161,8 @@ can not be read correctly in the first place: <LI><I>element_exclusion_list</I> +<LI><I>min_feature_length</I> + <LI><I>curvature_tolerant</I> <P>The <I>precision</I> keyword specifies how far away mesh nodes can be at maximum to @@ -170,10 +181,17 @@ calculated. by removing duplicate elements. </P> <P>With the optional <I>element_exclusion_list</I> keyword is used in mode 'write', LIGGGHTS(R)-PUBLIC -will write a list of elements which have more than the allowed 5 face neighbors per surface -element to a file, as well as those elements which have an angle below 0.181185 degrees. -The 'read' mode can then use this file and will skip the elements in the list. However, you can -also manually write such a file to exclude elements you do not want to have included +will write a list of elements which +</P> +<LI>have more than the allowed 5 face neighbors per surface + +<LI>have an angle below 0.0181185 degrees + +<LI>are duplicate + +<P>element to a file. The 'read' mode can then use this file and will skip the elements in +the list. However, you can also manually write such a file to exclude elements you do not +want to have included </P> <P>IMPORTANT NOTE: The <I>element_exclusion_list write</I> model works in serial only. However, this is not a real restriction, since you can generate the exclusion lists in serial, @@ -182,7 +200,14 @@ but then read them to import the mesh into a parallel simulation <P>IMPORTANT NOTE: If you use the 'heal' or 'element_exclusion_list' keywords, you should check the changes to the geometry, e.g. by using a <A HREF = "dump.html">dump mesh/stl</A> command. </P> -<P>The <I>curvature_toleran</I> keyword can simply turn off the check that +<P>With the <I>min_feature_length</I> option, you can exlude elements which do not belong +to an entity which has any element larger than <I>min_feature_length</I>. In this context, +'entity' is defined by the 'neighborhood' of the element. +<I>min_feature_length</I> also writes to the exclusion list, and can thus only be used along +with the 'element_exclusion_list' feature. This feature is only available in the +PREMIUM version of LIGGGHTS. +</P> +<P>The <I>curvature_tolerant</I> keyword can simply turn off the check that the <I>curvature</I> must not be larger than any angle in any mesh element. This is typically not recommended, but can be used as a last resort measure. </P> diff --git a/doc/fix_mesh_surface.txt b/doc/fix_mesh_surface.txt index 7ffe5de2d9745cb69dcf370a8c8646a59b07c398..a53fb3ddbc98c989cf3fc066aa5eb03330a90044 100644 --- a/doc/fix_mesh_surface.txt +++ b/doc/fix_mesh_surface.txt @@ -19,10 +19,12 @@ mesh/surface or mesh/surface/planar = style name of this fix command :l file = obligatory keyword :l filename = name of STL or VTK file containing the triangle mesh data :l zero or more premesh_keywords/premesh_value pairs may be appended :l -premesh_keyword = {type} or {precision} or {heal} or {element_exclusion_list} or {verbose} :l +premesh_keyword = {type} or {precision} or {heal} or {min_feature_length} or {element_exclusion_list} or {verbose} :l {type} value = atom type (material type) of the wall imported from the STL file + {region} value = ID of "region"_region.html to filter elements which are imported {precision} value = length mesh nodes this far away at maximum will be recognized as identical (length units) {heal} value = auto_remove_duplicates or no + {min_feature_length} value = exclude element if belongs to an entity where no element is larger than this (length units) {element_exclusion_list} values = mode element_exlusion_file mode = read or write element_exlusion_file = name of file containing the elements to be excluded @@ -37,6 +39,7 @@ mesh_keyword = {scale} or {move} or {rotate} or {temperature} or {mass_temperatu axis = obligatory keyword ax, ay, az = axis vector for rotation (length units) angle = obligatory keyword + ang = rotation angle (degrees) {temperature} value = T0 T0 = Temperature of the wall (temperature units) {mass_temperature} value = mt0 @@ -70,9 +73,15 @@ ASCII STL files or legacy ASCII VTK files. Style {mesh/surface} is a general sur {mesh/surface/planar} represents a planar mesh. {mesh/surface/planar} requires the mesh to consist of only 1 planar face. +The {region} keyword can be used to filter the elements which are imported. An element is only +imported if all of its vertices is inside the specified "region"_region.html. Please note that +the geometric extent of this "region"_region.html refer to the unscaled, unmoved, and unrotated +original state of the geometry. + Generall, you can apply scaling, offset and rotation to the imported mesh via keywords {scale}, -{move}, {rotate}. Operations are applied in the order as they are specified. The group-ID defines -which particles will "see" the mesh, in case it is used as a granular wall. +{move}, {rotate}. Operations are applied in the order as they are specified. The rotation via {rotate} is performed around the rotation axis that goes through the origin (0,0,0) and in the direction of {axis}. + +The group-ID defines which particles will "see" the mesh, in case it is used as a granular wall. One fix represents one wall with a specific material, where the material is identified via keyword {type}. If multiple meshes with different materials are desired, the respective @@ -106,7 +115,7 @@ If any of the obove rules is not fulfilled, a warning is generated. Keyword Error messages: The {curvature} must not be larger than any angle in any mesh element :l -There must be no element with an angle < 0.181185 degrees in any element (hard limit for angles) :l +There must be no element with an angle < 0.0181185 degrees in any element (hard limit for angles) :l The number of neighbor elements must be <= 5 for any element :l Mesh elements must not be duplicate :l Coplanar mesh elements that share an edge must not overlap :l @@ -126,6 +135,7 @@ can not be read correctly in the first place: {curvature} :l {heal} :l {element_exclusion_list} :l +{min_feature_length} :l {curvature_tolerant} :l The {precision} keyword specifies how far away mesh nodes can be at maximum to @@ -144,10 +154,15 @@ If LIGGGHTS(R)-PUBLIC stalls because of duplicate elements, you can try setting by removing duplicate elements. With the optional {element_exclusion_list} keyword is used in mode 'write', LIGGGHTS(R)-PUBLIC -will write a list of elements which have more than the allowed 5 face neighbors per surface -element to a file, as well as those elements which have an angle below 0.181185 degrees. -The 'read' mode can then use this file and will skip the elements in the list. However, you can -also manually write such a file to exclude elements you do not want to have included +will write a list of elements which + +have more than the allowed 5 face neighbors per surface :l +have an angle below 0.0181185 degrees :l +are duplicate :l + +element to a file. The 'read' mode can then use this file and will skip the elements in +the list. However, you can also manually write such a file to exclude elements you do not +want to have included IMPORTANT NOTE: The {element_exclusion_list write} model works in serial only. However, this is not a real restriction, since you can generate the exclusion lists in serial, @@ -156,7 +171,14 @@ but then read them to import the mesh into a parallel simulation IMPORTANT NOTE: If you use the 'heal' or 'element_exclusion_list' keywords, you should check the changes to the geometry, e.g. by using a "dump mesh/stl"_dump.html command. -The {curvature_toleran} keyword can simply turn off the check that +With the {min_feature_length} option, you can exlude elements which do not belong +to an entity which has any element larger than {min_feature_length}. In this context, +'entity' is defined by the 'neighborhood' of the element. +{min_feature_length} also writes to the exclusion list, and can thus only be used along +with the 'element_exclusion_list' feature. This feature is only available in the +PREMIUM version of LIGGGHTS. + +The {curvature_tolerant} keyword can simply turn off the check that the {curvature} must not be larger than any angle in any mesh element. This is typically not recommended, but can be used as a last resort measure. diff --git a/doc/fix_mesh_surface_stress.html b/doc/fix_mesh_surface_stress.html index 501a8cb5f52690c1dd4ee16890a42403bffe13c4..67ada2a1c9e21c6ef93146dec7353d1fc73eeaed 100644 --- a/doc/fix_mesh_surface_stress.html +++ b/doc/fix_mesh_surface_stress.html @@ -23,11 +23,11 @@ <LI>zero or more stress_keyword/value pairs may be appended -<LI>stress_keyword = <I>stress</I> or <I>wear</I> +<LI>stress_keyword = <I>reference_point</I>, <I>stress</I> or <I>wear</I> -<PRE> <I>stress</I> value = on or off - <I>reference_point</I> values = rx ry rz +<PRE> <I>reference_point</I> values = rx ry rz rx, ry, rz = coordinates of reference point + <I>stress</I> value = on or off <I>wear</I> value = finnie or off </PRE> @@ -39,12 +39,12 @@ <P><B>Description:</B> </P> <P>This fix is identical to <A HREF = "fix_mesh_surface.html">fix mesh/surface</A> but additionally -the pressure and shear force that the particles in the fix group exert on each +the average normal and shear stresses that the particles in the fix group exert on each triangle of the mesh is evaluated (which costs a bit of performance). Also, the total force and torque on the particle is calculated (see output info). The per-element forces can be dumped into VTK format using <A HREF = "dump.html">dump mesh/vtk</A>. </P> -<P>With the optional <I>stress</I> keyword, stress tracking can be turned off is desired. The +<P>With the optional <I>stress</I> keyword, stress tracking can be turned off if desired. The reference point for calculating the body torque can be controlled via the <I>referece_point</I> keyword. The optional <I>wear</I> keyword can activates a simple qualitative wear model (<I>finnie</I>) - for details on the model, see the seperate /doc/finnie-wear.pdf. The @@ -56,10 +56,10 @@ finnie constant k in Eqn. (4.23) has to be specified as follows: </PRE> <P><B>Restart, fix_modify, output, run start/stop, minimize info:</B> </P> -<P>This fix stores a global vector with 6 components for access by various +<P>This fix stores a global vector with 9 components for access by various <A HREF = "Section_howto.html#4_15">output commands</A>. The first 3 components are equal to the -total force on the mesh, the last 3 components store the total torque on the body -exerted by the particles. Other info see <A HREF = "fix_mesh.html">fix mesh</A>. +total force on the mesh, the next 3 components store the total torque on the body +exerted by the particles. Finally, the last 3 components are the coordinates (moved, scaled, rotated) of the reference point. Other info see <A HREF = "fix_mesh.html">fix mesh</A>. </P> <P><B>Related commands:</B> </P> @@ -68,8 +68,8 @@ exerted by the particles. Other info see <A HREF = "fix_mesh.html">fix mesh</A>. </P> <P><B>Default:</B> </P> -<P>stress = on -reference_point = 0. 0. 0. +<P>reference_point = 0. 0. 0. +stress = on wear = off </P> </HTML> diff --git a/doc/fix_mesh_surface_stress.txt b/doc/fix_mesh_surface_stress.txt index 2a482eabc51ce9e9065d489f76050511d36d260f..4fb2348cd6b24912e2d60a01826cb8d00aa873d8 100644 --- a/doc/fix_mesh_surface_stress.txt +++ b/doc/fix_mesh_surface_stress.txt @@ -16,10 +16,10 @@ ID, is documented in "fix"_fix.html command, the group-ID is ignored for this co mesh/surface/stress = style name of this fix command :l file filename premesh_keywords premesh_values mesh_keywords mesh_values surface_keyword surface_values are documented in "fix mesh/surface"_fix_mesh_surface.html. :l zero or more stress_keyword/value pairs may be appended :l -stress_keyword = {stress} or {wear} :l - {stress} value = on or off +stress_keyword = {reference_point}, {stress} or {wear} :l {reference_point} values = rx ry rz rx, ry, rz = coordinates of reference point + {stress} value = on or off {wear} value = finnie or off :pre :ule @@ -30,12 +30,12 @@ fix cad all mesh/surface/stress file mesh.stl type 1 wear finnie :pre [Description:] This fix is identical to "fix mesh/surface"_fix_mesh_surface.html but additionally -the pressure and shear force that the particles in the fix group exert on each +the average normal and shear stresses that the particles in the fix group exert on each triangle of the mesh is evaluated (which costs a bit of performance). Also, the total force and torque on the particle is calculated (see output info). The per-element forces can be dumped into VTK format using "dump mesh/vtk"_dump.html. -With the optional {stress} keyword, stress tracking can be turned off is desired. The +With the optional {stress} keyword, stress tracking can be turned off if desired. The reference point for calculating the body torque can be controlled via the {referece_point} keyword. The optional {wear} keyword can activates a simple qualitative wear model ({finnie}) - for details on the model, see the seperate /doc/finnie-wear.pdf. The @@ -47,10 +47,10 @@ fix id all property/global k_finnie peratomtypepair n_atomtypes value_11 value_1 [Restart, fix_modify, output, run start/stop, minimize info:] -This fix stores a global vector with 6 components for access by various +This fix stores a global vector with 9 components for access by various "output commands"_Section_howto.html#4_15. The first 3 components are equal to the -total force on the mesh, the last 3 components store the total torque on the body -exerted by the particles. Other info see "fix mesh"_fix_mesh.html. +total force on the mesh, the next 3 components store the total torque on the body +exerted by the particles. Finally, the last 3 components are the coordinates (moved, scaled, rotated) of the reference point. Other info see "fix mesh"_fix_mesh.html. [Related commands:] @@ -59,6 +59,6 @@ exerted by the particles. Other info see "fix mesh"_fix_mesh.html. [Default:] -stress = on reference_point = 0. 0. 0. +stress = on wear = off diff --git a/doc/fix_particletemplate_sphere.html b/doc/fix_particletemplate_sphere.html index ac6a5cd5ae0117b3dcf1532ebbe9db2e2924366c..eb9b4a8e393899d526649f3f36c34b51fe9e4764 100644 --- a/doc/fix_particletemplate_sphere.html +++ b/doc/fix_particletemplate_sphere.html @@ -27,14 +27,14 @@ <PRE><I>atom_type</I> value = atom type assigned to this particle template <I>density</I> values = random_style param1 (param2) - random_style = 'constant' or 'uniform' or 'gaussian' - param1 = density for 'constant', low value of density for 'uniform', expectancy value for 'gaussian' - param2 = omitted for 'constant', high value of density for 'uniform', sigma value for 'gaussian' + random_style = 'constant' + param1 = density for 'constant', + param2 = omitted for 'constant' <I>volume_limit</I> value = lowest particle volume allowed in simulation <I>radius</I> values = random_style param1 (param2) - random_style = 'constant' or 'uniform number' or 'uniform mass' or 'gaussian number' - param1 = radius for 'constant', low value of radius for 'uniform', mu value for 'gaussian' - param2 = omitted for 'constant', high value of radius for 'uniform', sigma value for 'gaussian' + random_style = 'constant' + param1 = radius for 'constant' + param2 = omitted for 'constant' <I>relative</I> value = yes or no no = set a flag for other commands that radius given here is abosulute (in length units) yes = set a flag for other commands that radius given here is relative (in % of a reference radius) @@ -50,23 +50,15 @@ <P>Define a particle that is used as input for a <A HREF = "fix_particledistribution_discrete.html">fix_particledistribution_discrete</A> command. You can choose the atom type, density and radius of the particles. For density and -radius, you can choose between 'constant', 'uniform' and 'gaussian' random styles. -Note that for radius, you can additionally choose between a number-based and mass-based -uniform distribution, where the latter is used more frequently typically. 'gaussian' for -radius only supports a number-based distribution. +radius, there is currently only a 'constant' style. Note that this is not a restriction since +multiple commands of style particletemplate/sphere can be used in a <A HREF = "fix_particledistribution_discrete.html">fix_particledistribution_discrete</A> +command so any kind of distribution can be approximated to any arbitrary precision. </P> <P>Keyword <I>relative</I> lets the user set a flag to let other commands know if the radii specified by this command are absolute (length units) or relative (in % of a reference radius). IMPORTANT NOTE: This setting should not be changed away from the default value (no) unless explicity required by another command! </P> -<P>It is thus possible to define a uniform or gaussian distribution on top of the discrete -distribution defined by <A HREF = "fix_particledistribution_discrete.html">fix_particledistribution_discrete</A>. -</P> -<P>IMPORTANT NOTE: As opposed to the number-based distributions, this fix uses the more common -distribution based on mass-% for the radius distribution (as does -<A HREF = "fix_particledistribution_discrete.html">fix_particledistribution_discrete</A>). -</P> <P>LIGGGHTS(R)-PUBLIC will throw an error if the particle volume is too small compared to machine precision. If you are sure you know what you are doing you can override the default limit of 1e-12. </P> diff --git a/doc/fix_particletemplate_sphere.txt b/doc/fix_particletemplate_sphere.txt index 2fa150dd9f9aa4bbc89122c63394e1c8ef985170..2acb882b71884332c9d20fd0014998f14766c0d9 100644 --- a/doc/fix_particletemplate_sphere.txt +++ b/doc/fix_particletemplate_sphere.txt @@ -19,14 +19,14 @@ zero or more keyword/value pairs can be appended :l keyword = {atom_type} or {density} or {volume_limit} or {radius} or {relative} :l {atom_type} value = atom type assigned to this particle template {density} values = random_style param1 (param2) - random_style = 'constant' or 'uniform' or 'gaussian' - param1 = density for 'constant', low value of density for 'uniform', expectancy value for 'gaussian' - param2 = omitted for 'constant', high value of density for 'uniform', sigma value for 'gaussian' + random_style = 'constant' + param1 = density for 'constant', + param2 = omitted for 'constant' {volume_limit} value = lowest particle volume allowed in simulation {radius} values = random_style param1 (param2) - random_style = 'constant' or 'uniform number' or 'uniform mass' or 'gaussian number' - param1 = radius for 'constant', low value of radius for 'uniform', mu value for 'gaussian' - param2 = omitted for 'constant', high value of radius for 'uniform', sigma value for 'gaussian' + random_style = 'constant' + param1 = radius for 'constant' + param2 = omitted for 'constant' {relative} value = yes or no no = set a flag for other commands that radius given here is abosulute (in length units) yes = set a flag for other commands that radius given here is relative (in % of a reference radius) :pre @@ -41,23 +41,15 @@ fix pts1 all particletemplate/sphere 1 atom_type 1 density constant 2500 radius Define a particle that is used as input for a "fix_particledistribution_discrete"_fix_particledistribution_discrete.html command. You can choose the atom type, density and radius of the particles. For density and -radius, you can choose between 'constant', 'uniform' and 'gaussian' random styles. -Note that for radius, you can additionally choose between a number-based and mass-based -uniform distribution, where the latter is used more frequently typically. 'gaussian' for -radius only supports a number-based distribution. +radius, there is currently only a 'constant' style. Note that this is not a restriction since +multiple commands of style particletemplate/sphere can be used in a "fix_particledistribution_discrete"_fix_particledistribution_discrete.html +command so any kind of distribution can be approximated to any arbitrary precision. Keyword {relative} lets the user set a flag to let other commands know if the radii specified by this command are absolute (length units) or relative (in % of a reference radius). IMPORTANT NOTE: This setting should not be changed away from the default value (no) unless explicity required by another command! -It is thus possible to define a uniform or gaussian distribution on top of the discrete -distribution defined by "fix_particledistribution_discrete"_fix_particledistribution_discrete.html. - -IMPORTANT NOTE: As opposed to the number-based distributions, this fix uses the more common -distribution based on mass-% for the radius distribution (as does -"fix_particledistribution_discrete"_fix_particledistribution_discrete.html). - LIGGGHTS(R)-PUBLIC will throw an error if the particle volume is too small compared to machine precision. If you are sure you know what you are doing you can override the default limit of 1e-12. diff --git a/doc/fix_poems.html b/doc/fix_poems.html index 49e42ded1977edd3eeb0f177dc41fd7f42cf5bf8..078ad5394e5e34d632426bb5a96ffd02504fdf62 100644 --- a/doc/fix_poems.html +++ b/doc/fix_poems.html @@ -13,8 +13,8 @@ </H3> <P>Syntax: </P> -<PRE>fix ID group-ID poems keyword values -</PRE> +<P>fix ID group-ID poems keyword values modelType keyword:pre +</P> <UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command <LI>poems = style name of this fix command @@ -25,122 +25,3 @@ <I>molecule</I> values = none <I>file</I> values = filename </PRE> - -</UL> -<P><B>Examples:</B> -</P> -<PRE>fix 3 fluid poems group clump1 clump2 clump3 -fix 3 fluid poems file cluster.list -</PRE> -<P><B>Description:</B> -</P> -<P>Treats one or more sets of atoms as coupled rigid bodies. This means -that each timestep the total force and torque on each rigid body is -computed and the coordinates and velocities of the atoms are updated -so that the collection of bodies move as a coupled set. This can be -useful for treating a large biomolecule as a collection of connected, -coarse-grained particles. -</P> -<P>The coupling, associated motion constraints, and time integration is -performed by the software package <A HREF = "http://www.rpi.edu/~anderk5/lab">Parallelizable Open source -Efficient Multibody Software (POEMS)</A> which computes the -constrained rigid-body motion of articulated (jointed) multibody -systems <A HREF = "#Anderson">(Anderson)</A>. POEMS was written and is distributed -by Prof Kurt Anderson, his graduate student Rudranarayan Mukherjee, -and other members of his group at Rensselaer Polytechnic Institute -(RPI). Rudranarayan developed the LIGGGHTS(R)-PUBLIC/POEMS interface. For -copyright information on POEMS and other details, please refer to the -documents in the poems directory distributed with LIGGGHTS(R)-PUBLIC. -</P> - - -<P>This fix updates the positions and velocities of the rigid atoms with -a constant-energy time integration, so you should not update the same -atoms via other fixes (e.g. nve, nvt, npt, temp/rescale, langevin). -</P> -<P>Each body must have a non-degenerate inertia tensor, which means if -must contain at least 3 non-collinear atoms. Which atoms are in which -bodies can be defined via several options. -</P> -<P>For option <I>group</I>, each of the listed groups is treated as a rigid -body. Note that only atoms that are also in the fix group are -included in each rigid body. -</P> -<P>For option <I>molecule</I>, each set of atoms in the group with a different -molecule ID is treated as a rigid body. -</P> -<P>For option <I>file</I>, sets of atoms are read from the specified file and -each set is treated as a rigid body. Each line of the file specifies -a rigid body in the following format: -</P> -<P>ID type atom1-ID atom2-ID atom3-ID ... -</P> -<P>ID as an integer from 1 to M (the number of rigid bodies). Type is -any integer; it is not used by the fix poems command. The remaining -arguments are IDs of atoms in the rigid body, each typically from 1 to -N (the number of atoms in the system). Only atoms that are also in -the fix group are included in each rigid body. Blank lines and lines -that begin with '#' are skipped. -</P> -<P>A connection between a pair of rigid bodies is inferred if one atom is -common to both bodies. The POEMS solver treats that atom as a -spherical joint with 3 degrees of freedom. Currently, a collection of -bodies can only be connected by joints as a linear chain. The entire -collection of rigid bodies can represent one or more chains. Other -connection topologies (tree, ring) are not allowed, but will be added -later. Note that if no joints exist, it is more efficient to use the -<A HREF = "fix_rigid.html">fix rigid</A> command to simulate the system. -</P> -<P>When the poems fix is defined, it will print out statistics on the -total # of clusters, bodies, joints, atoms involved. A cluster in -this context means a set of rigid bodies connected by joints. -</P> -<P>For computational efficiency, you should turn off pairwise and bond -interactions within each rigid body, as they no longer contribute to -the motion. The "neigh_modify exclude" and "delete_bonds" commands -can be used to do this if each rigid body is a group. -</P> -<P>For computational efficiency, you should only define one fix poems -which includes all the desired rigid bodies. LIGGGHTS(R)-PUBLIC will allow -multiple poems fixes to be defined, but it is more expensive. -</P> -<P>The degrees-of-freedom removed by coupled rigid bodies are accounted -for in temperature and pressure computations. Similarly, the rigid -body contribution to the pressure virial is also accounted for. The -latter is only correct if forces within the bodies have been turned -off, and there is only a single fix poems defined. -</P> -<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B> -</P> -<P>No information about this fix is written to <A HREF = "restart.html">binary restart -files</A>. None of the <A HREF = "fix_modify.html">fix_modify</A> options -are relevant to this fix. No global or per-atom quantities are stored -by this fix for access by various <A HREF = "Section_howto.html#howto_8">output -commands</A>. No parameter of this fix can -be used with the <I>start/stop</I> keywords of the <A HREF = "run.html">run</A> command. -This fix is not invoked during <A HREF = "minimize.html">energy minimization</A>. -</P> -<P><B>Restrictions:</B> -</P> -<P>This fix is part of the POEMS package. It is only enabled if LIGGGHTS(R)-PUBLIC -was built with that package, which also requires the POEMS library be -built and linked with LIGGGHTS(R)-PUBLIC. See the <A HREF = "Section_start.html#start_3">Making -LIGGGHTS(R)-PUBLIC</A> section for more info. -</P> -<P><B>Related commands:</B> -</P> -<P><A HREF = "fix_rigid.html">fix rigid</A>, <A HREF = "delete_bonds.html">delete_bonds</A>, -<A HREF = "neigh_modify.html">neigh_modify</A> exclude -</P> -<P><B>Default:</B> none -</P> -<HR> - -<A NAME = "Anderson"></A> - -<P><B>(Anderson)</B> Anderson, Mukherjee, Critchley, Ziegler, and Lipton -"POEMS: Parallelizable Open-source Efficient Multibody Software ", -Engineering With Computers (2006). (<A HREF = "http://dx.doi.org/10.1007/s00366-006-0026-x">link to -paper</A>) -</P> -</HTML> diff --git a/doc/fix_poems.txt b/doc/fix_poems.txt index b643f9eb2195da20fb0426112687957c3db46dc0..9c2275b18c7d74d3a3adb5c0c554d18a3a108829 100644 --- a/doc/fix_poems.txt +++ b/doc/fix_poems.txt @@ -10,7 +10,7 @@ fix poems command :h3 Syntax: -fix ID group-ID poems keyword values :pre +fix ID group-ID poems keyword values modelType keyword:pre ID, group-ID are documented in "fix"_fix.html command :ulb,l poems = style name of this fix command :l @@ -18,30 +18,37 @@ keyword = {group} or {file} or {molecule} :l {group} values = list of group IDs {molecule} values = none {file} values = filename :pre +modelType = segment joint model :1 +keyword = {SFJ} or {SF} :1 + {SFJ} = Spherrical Flexible Joint + {SJ} = Spherical Joint :pre :ule [Examples:] fix 3 fluid poems group clump1 clump2 clump3 -fix 3 fluid poems file cluster.list :pre +fix 3 fluid poems file cluster.list +fix 1 all poems file data/segments_joints.poems modelType SFJ :pre [Description:] -Treats one or more sets of atoms as coupled rigid bodies. This means -that each timestep the total force and torque on each rigid body is +Treats one or more sets of atoms as coupled rigid segment. A list of +rigid segments joint tegether making up one system; Several list of +rigid segments compose several system. This means that in one system +at each timestep the total force and torque on each rigid segment is computed and the coordinates and velocities of the atoms are updated -so that the collection of bodies move as a coupled set. This can be +so that the collection of segments move as a coupled set. This can be useful for treating a large biomolecule as a collection of connected, coarse-grained particles. The coupling, associated motion constraints, and time integration is performed by the software package "Parallelizable Open source Efficient Multibody Software (POEMS)"_poems which computes the -constrained rigid-body motion of articulated (jointed) multibody +constrained rigid-segment motion of articulated (jointed) multibody systems "(Anderson)"_#Anderson. POEMS was written and is distributed by Prof Kurt Anderson, his graduate student Rudranarayan Mukherjee, and other members of his group at Rensselaer Polytechnic Institute -(RPI). Rudranarayan developed the LIGGGHTS(R)-PUBLIC/POEMS interface. For +(RPI). Rudranarayan developed the original POEMS interface. For copyright information on POEMS and other details, please refer to the documents in the poems directory distributed with LIGGGHTS(R)-PUBLIC. @@ -51,56 +58,57 @@ This fix updates the positions and velocities of the rigid atoms with a constant-energy time integration, so you should not update the same atoms via other fixes (e.g. nve, nvt, npt, temp/rescale, langevin). -Each body must have a non-degenerate inertia tensor, which means if +Each segment must have a non-degenerate inertia tensor, which means if must contain at least 3 non-collinear atoms. Which atoms are in which -bodies can be defined via several options. +segments can be defined via several options. For option {group}, each of the listed groups is treated as a rigid -body. Note that only atoms that are also in the fix group are -included in each rigid body. +segment. Note that only atoms that are also in the fix group are +included in each rigid segment. For option {molecule}, each set of atoms in the group with a different -molecule ID is treated as a rigid body. +molecule ID is treated as a rigid segment. For option {file}, sets of atoms are read from the specified file and -each set is treated as a rigid body. Each line of the file specifies -a rigid body in the following format: +each set is treated as a rigid segment. Each line of the file specifies +a rigid segment in the following format: ID type atom1-ID atom2-ID atom3-ID ... -ID as an integer from 1 to M (the number of rigid bodies). Type is +ID as an integer from 1 to M (the number of rigid segments). Type is any integer; it is not used by the fix poems command. The remaining -arguments are IDs of atoms in the rigid body, each typically from 1 to +arguments are IDs of atoms in the rigid segment, each typically from 1 to N (the number of atoms in the system). Only atoms that are also in -the fix group are included in each rigid body. Blank lines and lines +the fix group are included in each rigid segment. Blank lines and lines that begin with '#' are skipped. -A connection between a pair of rigid bodies is inferred if one atom is -common to both bodies. The POEMS solver treats that atom as a -spherical joint with 3 degrees of freedom. Currently, a collection of -bodies can only be connected by joints as a linear chain. The entire -collection of rigid bodies can represent one or more chains. Other +A connection between a pair of rigid segments is inferred if one atom is +common to both segments. The POEMS solver treats that atom as a +spherical joint (SJ) or spherical flexible joint (SFJ) with 3 degrees of freedom. +Currently, a collection of segments can only be connected by joints as +a linear chain. The entire collection of rigid segments can represent +one or more chains (one or more systems). Other connection topologies (tree, ring) are not allowed, but will be added later. Note that if no joints exist, it is more efficient to use the "fix rigid"_fix_rigid.html command to simulate the system. When the poems fix is defined, it will print out statistics on the -total # of clusters, bodies, joints, atoms involved. A cluster in -this context means a set of rigid bodies connected by joints. +total # of clusters, segments, joints, atoms involved. A cluster in +this context means a set of rigid segments connected by joints. For computational efficiency, you should turn off pairwise and bond -interactions within each rigid body, as they no longer contribute to +interactions within each rigid segment, as they no longer contribute to the motion. The "neigh_modify exclude" and "delete_bonds" commands -can be used to do this if each rigid body is a group. +can be used to do this if each rigid segment is a group. For computational efficiency, you should only define one fix poems -which includes all the desired rigid bodies. LIGGGHTS(R)-PUBLIC will allow +which includes all the desired rigid segments. LIGGGHTS(R)-PUBLIC will allow multiple poems fixes to be defined, but it is more expensive. -The degrees-of-freedom removed by coupled rigid bodies are accounted +The degrees-of-freedom removed by coupled rigid segments are accounted for in temperature and pressure computations. Similarly, the rigid -body contribution to the pressure virial is also accounted for. The -latter is only correct if forces within the bodies have been turned +segment contribution to the pressure virial is also accounted for. The +latter is only correct if forces within the segments have been turned off, and there is only a single fix poems defined. [Restart, fix_modify, output, run start/stop, minimize info:] diff --git a/doc/fix_property_atom_timetracer.html b/doc/fix_property_atom_timetracer.html new file mode 100644 index 0000000000000000000000000000000000000000..efcf0387c4679935d679b45d4a98f527d6783097 --- /dev/null +++ b/doc/fix_property_atom_timetracer.html @@ -0,0 +1,82 @@ +<HTML> +<CENTER><A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> +</CENTER> + + + + + + +<HR> + +<H3>fix property/atom/timetracer command +</H3> +<P><B>Syntax:</B> +</P> +<PRE>fix id group property/atom/timetracer keyword value ... +</PRE> +<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command + +<LI>property/atom/timetracer = style name of this fix command + +<LI>zero or more keyword/value pairs may be appended to args + +<LI>keyword = <I>add_region</I> or <I>check_region_every</I> + +<PRE> <I>add_region</I> value = <I>region-ID</I> + region-ID = ID of region to be added to list of regions where residence time is evaluated + <I>check_region_every</I> value = n + n = check every that many time-step if atom are in region +</PRE> + +</UL> +<P><B>Examples:</B> +</P> +<PRE>fix tracer all property/atom/timetracer add_region tracereg +</PRE> +<P><B>Description:</B> +</P> +<P>Fix property/atom/timetracer computes the residence time of particles +in the simulation domain and (optionally) a list of regions. +</P> +<P>Since the look-up if a particle is in a specific region can be +compuationally costly, keyword <I>check_region_every</I> can be used to +control how often the region is checked. Every <I>check_region_every</I> +time-steps, the lookup is performed and the residence time contribution +for each lookup is dt*<I>check_region_every</I>, where dt is the time-step +size. However, be careful not to choose this value too large, in this case +you could skip particles passing through a region. +</P> +<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B> +</P> +<P>Information about this fix is written to <A HREF = "restart.html">binary restart files</A> . +</P> +<P>In case no regions are specified, this fix computes a per-atom vector +(the residence time of particles in the simulation domain) which can be +accessed by various <A HREF = "Section_howto.html#howto_8">output commands</A>. +In case one or more optional regions are specified, this fix computes +a per-atom array, where the first value for each particle is the residence +time in the simulation domain and the following values are the residence +time in the specified regions (in the order in which the regions are +specified). +</P> +<P>This fix computes a N-vector of residence times, where N=1+number of +regions specified, which can be accessed by various <A HREF = "Section_howto.html#howto_8">output +commands</A>. The vector components are the +average residence time in the fix group for the whole simulation domain +(first value) and for each region (following values). The order +is following the order in which the regions are specified. +</P> +<P><B>Restrictions:</B> +</P> +<P>Currently, this feature does not support multi-sphere particles. +</P> +<P><B>Related commands:</B> +</P> +<P><A HREF = "compute_nparticles_tracer_region.html">compute nparticles/tracer/region</A> +</P> +<P><B>Default:</B> +</P> +<P>check_region_every = 10 +</P> +</HTML> diff --git a/doc/fix_property_atom_timetracer.txt b/doc/fix_property_atom_timetracer.txt new file mode 100644 index 0000000000000000000000000000000000000000..88d92298716741a59c318c8a1bf3f85604e88573 --- /dev/null +++ b/doc/fix_property_atom_timetracer.txt @@ -0,0 +1,73 @@ +"LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c + +:link(liws,http://www.cfdem.com) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix property/atom/timetracer command :h3 + +[Syntax:] + +fix id group property/atom/timetracer keyword value ... :pre + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +property/atom/timetracer = style name of this fix command :l +zero or more keyword/value pairs may be appended to args :l +keyword = {add_region} or {check_region_every} :l + {add_region} value = {region-ID} + region-ID = ID of region to be added to list of regions where residence time is evaluated + {check_region_every} value = n + n = check every that many time-step if atom are in region :pre + +:ule + +[Examples:] + +fix tracer all property/atom/timetracer add_region tracereg :pre + +[Description:] + +Fix property/atom/timetracer computes the residence time of particles +in the simulation domain and (optionally) a list of regions. + +Since the look-up if a particle is in a specific region can be +compuationally costly, keyword {check_region_every} can be used to +control how often the region is checked. Every {check_region_every} +time-steps, the lookup is performed and the residence time contribution +for each lookup is dt*{check_region_every}, where dt is the time-step +size. However, be careful not to choose this value too large, in this case +you could skip particles passing through a region. + +[Restart, fix_modify, output, run start/stop, minimize info:] + +Information about this fix is written to "binary restart files"_restart.html . + +In case no regions are specified, this fix computes a per-atom vector +(the residence time of particles in the simulation domain) which can be +accessed by various "output commands"_Section_howto.html#howto_8. +In case one or more optional regions are specified, this fix computes +a per-atom array, where the first value for each particle is the residence +time in the simulation domain and the following values are the residence +time in the specified regions (in the order in which the regions are +specified). + +This fix computes a N-vector of residence times, where N=1+number of +regions specified, which can be accessed by various "output +commands"_Section_howto.html#howto_8. The vector components are the +average residence time in the fix group for the whole simulation domain +(first value) and for each region (following values). The order +is following the order in which the regions are specified. + +[Restrictions:] + +Currently, this feature does not support multi-sphere particles. + +[Related commands:] + +"compute nparticles/tracer/region"_compute_nparticles_tracer_region.html + +[Default:] + +check_region_every = 10 diff --git a/doc/githubAccess_non-public.html b/doc/githubAccess_non-public.html index f0e028399295634566412085aff2b22b7592ec55..40ec39dc92050f2eb9e5beb4f942affb10a90925 100644 --- a/doc/githubAccess_non-public.html +++ b/doc/githubAccess_non-public.html @@ -5,16 +5,16 @@ - - - - <HR> <H3>githubAccess_non-public </H3> <HR> + + + + <P><B>Description:</B> </P> <P>This routine describes how to setup a github account and pull repositories of the CFDEMproject. diff --git a/doc/githubAccess_non-public.txt b/doc/githubAccess_non-public.txt index 35cb281d7cce0bc8d7096bbab94fe3092f2147df..e3eba76b8ab77bad7de6d00d01628d2d4bbd9971 100644 --- a/doc/githubAccess_non-public.txt +++ b/doc/githubAccess_non-public.txt @@ -1,14 +1,15 @@ -"CFDEMproject WWW Site"_lws - "CFDEM Commands"_lc :c +"CFDEMproject WWW Site"_liws - "CFDEM Commands"_lc :c -:link(lws,http://www.cfdem.com) +:link(liws,http://www.cfdem.com) :link(lc,CFDEMcoupling_Manual.html#comm) -:link(github,http://github.com) -:link(gitHelp,http://help.github.com/linux-set-up-git) :line githubAccess_non-public :h3 :line +:link(github,http://github.com) +:link(gitHelp,http://help.github.com/linux-set-up-git) + [Description:] This routine describes how to setup a github account and pull repositories of the CFDEMproject. diff --git a/doc/githubAccess_public.html b/doc/githubAccess_public.html index 93e223a3a08818aed0ba52d4e31662a782153cc3..b9a95c82ccd47197d8d4e4848f5640248221478c 100644 --- a/doc/githubAccess_public.html +++ b/doc/githubAccess_public.html @@ -5,16 +5,16 @@ - - - - <HR> <H3>githubAccess_public </H3> <HR> + + + + <P><B>Description:</B> </P> <P>This routine describes how to setup a github account and pull repositories of the CFDEMproject. diff --git a/doc/githubAccess_public.txt b/doc/githubAccess_public.txt index 494614ba7c5eefaf713103140f27a5d197518695..813f4f1353a569ea3f33fc94adcf78b0b4fe35a0 100644 --- a/doc/githubAccess_public.txt +++ b/doc/githubAccess_public.txt @@ -1,14 +1,15 @@ -"CFDEMproject WWW Site"_lws - "CFDEM Commands"_lc :c +"CFDEMproject WWW Site"_liws - "CFDEM Commands"_lc :c -:link(lws,http://www.cfdem.com) +:link(liws,http://www.cfdem.com) :link(lc,CFDEMcoupling_Manual.html#comm) -:link(github,http://github.com) -:link(gitHelp,http://help.github.com/linux-set-up-git) :line githubAccess_public :h3 :line +:link(github,http://github.com) +:link(gitHelp,http://help.github.com/linux-set-up-git) + [Description:] This routine describes how to setup a github account and pull repositories of the CFDEMproject. diff --git a/doc/gran_cohesion_easo_capillary_viscous.html b/doc/gran_cohesion_easo_capillary_viscous.html index f5be9b50eca068a213cc58a916bc0d6dbd7c84ef..1f3ec9a1a8eae89ff06a6cca2b3dba5efcd01263 100644 --- a/doc/gran_cohesion_easo_capillary_viscous.html +++ b/doc/gran_cohesion_easo_capillary_viscous.html @@ -9,12 +9,18 @@ <HR> -<H3>gran cohesion easo/capillary/viscous +<H3>gran cohesion easo/capillary/viscous command </H3> <P><B>Syntax:</B> </P> <PRE>cohesion easo/capillary/viscous </PRE> +<LI>zero or more keyword/value pairs may be appended to the end (after all models are specified) + +<PRE> <I>tangential_reduce</I> values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model +</PRE> <P><B>Description:</B> </P> <P>This model can be used as part of <A HREF = "pair_gran.html">pair gran</A> @@ -114,6 +120,13 @@ fix id all property/global fluidViscosity scalar value fix id all property/global contactAngle peratomtype value_1 value_2 ... (value_i=value for contact angle of atom type i and fluid) </PRE> +<P>The optional keyword <I>tangential_reduce</I> defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If <I>tangential_reduce</I> = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) +</P> <P><B>Restrictions:</B> </P> <P>This model can ONLY be used as part of <A HREF = "pair_gran.html">pair gran</A>, not as part @@ -159,4 +172,8 @@ after a <A HREF = "run.html">run 0</A> command. <P><B>(Soulie)</B> Soulie, Cherblanc, Youssoufi, Saix, Intl. J Numerical and Analytical Methods in Geomechanics, p213, 30 (2006) </P> +<P><B>Default:</B> +</P> +<P><I>tangential_reduce</I> = 'off' +</P> </HTML> diff --git a/doc/gran_cohesion_easo_capillary_viscous.txt b/doc/gran_cohesion_easo_capillary_viscous.txt index 49d108b102a934ac9540fb2a4fcae0634e3cad09..3b087314d9fe61ad52560373dffcff9fdddb3b18 100644 --- a/doc/gran_cohesion_easo_capillary_viscous.txt +++ b/doc/gran_cohesion_easo_capillary_viscous.txt @@ -6,13 +6,16 @@ :line -gran cohesion easo/capillary/viscous :h3 +gran cohesion easo/capillary/viscous command :h3 [Syntax:] cohesion easo/capillary/viscous :pre - +zero or more keyword/value pairs may be appended to the end (after all models are specified) :l + {tangential_reduce} values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model :pre [Description:] @@ -113,6 +116,13 @@ fix id all property/global fluidViscosity scalar value fix id all property/global contactAngle peratomtype value_1 value_2 ... (value_i=value for contact angle of atom type i and fluid) :pre +The optional keyword {tangential_reduce} defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If {tangential_reduce} = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) + [Restrictions:] This model can ONLY be used as part of "pair gran"_pair_gran.html, not as part @@ -153,3 +163,6 @@ The cohesion model is not available for "atom_style"_atom_style.html superquadri :link(Soulie) [(Soulie)] Soulie, Cherblanc, Youssoufi, Saix, Intl. J Numerical and Analytical Methods in Geomechanics, p213, 30 (2006) +[Default:] + +{tangential_reduce} = 'off' diff --git a/doc/gran_cohesion_sjkr.html b/doc/gran_cohesion_sjkr.html index 1316102f2cbfe6ca5c4fcb54606494e25a7f9a03..51d858cf62e94b9c611e2626d22aa61ad830ef62 100644 --- a/doc/gran_cohesion_sjkr.html +++ b/doc/gran_cohesion_sjkr.html @@ -9,12 +9,18 @@ <HR> -<H3>gran cohesion sjkr +<H3>gran cohesion sjkr command </H3> <P><B>Syntax:</B> </P> <PRE>cohesion sjkr </PRE> +<LI>zero or more keyword/value pairs may be appended to the end (after all models are specified) + +<PRE> <I>tangential_reduce</I> values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model +</PRE> <P><B>Description:</B> </P> <P>This model can be used as part of <A HREF = "pair_gran.html">pair gran</A> and @@ -40,6 +46,13 @@ For <I>sjkr</I>, the sphere-sphere contact area is calculated as (http://mathwor </PRE> <P>IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... </P> +<P>The optional keyword <I>tangential_reduce</I> defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If <I>tangential_reduce</I> = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) +</P> <P><B>Restrictions:</B> </P> <P>The cohesion model has been derived for the Hertzian Style, it may note be @@ -47,4 +60,8 @@ appropriate for the Hookean styles. </P> <P>It is not available for <A HREF = "atom_style.html">atom_style</A> superquadric </P> +<P><B>Default:</B> +</P> +<P><I>tangential_reduce</I> = 'off' +</P> </HTML> diff --git a/doc/gran_cohesion_sjkr.txt b/doc/gran_cohesion_sjkr.txt index 0786ae7ff7068a251d18bbebd8d470c1b6b2a6f2..7b9a6c5292925f93f66394295ab27419cfba9416 100644 --- a/doc/gran_cohesion_sjkr.txt +++ b/doc/gran_cohesion_sjkr.txt @@ -6,12 +6,17 @@ :line -gran cohesion sjkr :h3 +gran cohesion sjkr command :h3 [Syntax:] cohesion sjkr :pre +zero or more keyword/value pairs may be appended to the end (after all models are specified) :l + {tangential_reduce} values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model :pre + [Description:] This model can be used as part of "pair gran"_pair_gran.html and @@ -37,9 +42,21 @@ fix id all property/global cohesionEnergyDensity peratomtypepair n_atomtypes val IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... +The optional keyword {tangential_reduce} defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If {tangential_reduce} = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) + [Restrictions:] The cohesion model has been derived for the Hertzian Style, it may note be appropriate for the Hookean styles. It is not available for "atom_style"_atom_style.html superquadric + + +[Default:] + +{tangential_reduce} = 'off' diff --git a/doc/gran_cohesion_sjkr2.html b/doc/gran_cohesion_sjkr2.html index bbaa7b482cbb88fd2d4aae991eb4e854067f6466..dc52cfac8d3e6f88f7800a87696f385f1cb154a8 100644 --- a/doc/gran_cohesion_sjkr2.html +++ b/doc/gran_cohesion_sjkr2.html @@ -9,12 +9,18 @@ <HR> -<H3>gran cohesion sjkr2 +<H3>gran cohesion sjkr2 command </H3> <P><B>Syntax:</B> </P> <PRE>cohesion sjkr2 </PRE> +<LI>zero or more keyword/value pairs may be appended to the end (after all models are specified) + +<PRE> <I>tangential_reduce</I> values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model +</PRE> <P><B>Description:</B> </P> <P>This model can be used as part of <A HREF = "pair_gran.html">pair gran</A> and @@ -41,11 +47,21 @@ appropriate for the Hookean styles. </P> <P>IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... </P> +<P>The optional keyword <I>tangential_reduce</I> defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If <I>tangential_reduce</I> = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) +</P> <P><B>Restrictions:</B> </P> <P>The cohesion model has been derived for the Hertzian Style, it may note be appropriate for the Hookean styles. </P> <P>It is not available for <A HREF = "atom_style.html">atom_style</A> superquadric +<B>Default:</B> +</P> +<P><I>tangential_reduce</I> = 'off' </P> </HTML> diff --git a/doc/gran_cohesion_sjkr2.txt b/doc/gran_cohesion_sjkr2.txt index 25ff6c0a59056de0c2c2ffa94b8083d31ba73907..d0ee173a938c9c1c384293388346004da0db2cde 100644 --- a/doc/gran_cohesion_sjkr2.txt +++ b/doc/gran_cohesion_sjkr2.txt @@ -6,12 +6,17 @@ :line -gran cohesion sjkr2 :h3 +gran cohesion sjkr2 command :h3 [Syntax:] cohesion sjkr2 :pre +zero or more keyword/value pairs may be appended to the end (after all models are specified) :l + {tangential_reduce} values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model :pre + [Description:] This model can be used as part of "pair gran"_pair_gran.html and @@ -38,9 +43,19 @@ appropriate for the Hookean styles. IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... +The optional keyword {tangential_reduce} defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If {tangential_reduce} = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) + [Restrictions:] The cohesion model has been derived for the Hertzian Style, it may note be appropriate for the Hookean styles. It is not available for "atom_style"_atom_style.html superquadric +[Default:] + +{tangential_reduce} = 'off' diff --git a/doc/gran_cohesion_washino_capillary_viscous.html b/doc/gran_cohesion_washino_capillary_viscous.html index e30cfa5b61f81248b5536fc5d303b5ba71f99a84..7485d30c0606a96565eeb39aeadb609f689074c1 100644 --- a/doc/gran_cohesion_washino_capillary_viscous.html +++ b/doc/gran_cohesion_washino_capillary_viscous.html @@ -9,11 +9,23 @@ <HR> -<H3>gran cohesion washino/capillary/viscous +<H3>gran cohesion washino/capillary/viscous command </H3> <P><B>Syntax:</B> </P> -<PRE>cohesion washino/capillary/viscous +<PRE>cohesion washino/capillary/viscous [other model_type/model_name pairs as described <A HREF = "pair_gran.html">here</A> ] keyword values +</PRE> +<LI>zero or more keyword/value pairs may be appended to the end (after all models are specified) + +<PRE> <I>limitLiquidContent</I> values = 'on' or 'off' + on = enables the model parameter <I>maxLiquidContent</I> + off = standard implementation without a limiter for the per particle liquid content + <I>modifyLbVolume</I> values = 'on' or 'off' + on = enables the model parameter <I>lbVolumeFraction</I> + off = standard implementation with lbVolumeFraction = 0.05 + <I>tangential_reduce</I> values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model </PRE> <P><B>Description:</B> </P> @@ -27,7 +39,9 @@ to the liquid bridge force, i.e. <I>radius</I>*<I>maxSeparationDistanceRatio</I> the effective contact radius of the particles. </P> <P>The model parameter <I>maxLiquidContent</I> allows to limit the maximum per particle -liquid content. +liquid content. (enabled by keyword <I>limitLiquidContent</I>) +</P> +<P>The model parameter <I>lbVolumeFraction</I> defines the amout of liquid that formes the liquid bridge with a neighbouring particle. (enabled by the keyword <I>modifyLbVolume</I>) </P> <HR> @@ -35,7 +49,7 @@ liquid content. </P> <P><I>Vbond</I>, the volume of surface liquid involved in the bridge, is given by </P> -<PRE>Vbond = 0.05*(surfaceLiquidVolI+surfaceLiquidVolJ) +<PRE>Vbond = lbVolumeFraction * (surfaceLiquidVolI+surfaceLiquidVolJ) </PRE> where <I>surfaceLiquidVolI/J</I> is the surface liquid volume attached to particle i/j. This model assumes that both formation distance and rupture distance @@ -116,6 +130,13 @@ fix id all property/global contactAngle peratomtype value_1 value_2 ... fix id all property/global maxLiquidContent peratomtype value_1 value_2 ... (value_i=value for contact angle of atom type i and fluid) </PRE> +<P>The optional keyword <I>tangential_reduce</I> defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If <I>tangential_reduce</I> = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) +</P> <P><B>Output:</B> </P> <P>This gran model stores a couple of per-particle properties, for access @@ -137,6 +158,10 @@ of a <A HREF = "fix_wall_gran.html">fix wall/gran</A>. </P> <P>The cohesion model is not available for <A HREF = "atom_style.html">atom_style</A> superquadric </P> +<P><B>Default:</B> +</P> +<P>lbVolumeFraction = 0.05 +</P> <P><B>References:</B> </P> <A NAME = "Lian"></A> @@ -151,4 +176,8 @@ of a <A HREF = "fix_wall_gran.html">fix wall/gran</A>. <P><B>(Rabinovitch)</B> Rabinovitch, Esayanur, Moudil, Langmuir, p10992, 21 (2005) </P> +<P><B>Default:</B> +</P> +<P><I>tangential_reduce</I> = 'off' +</P> </HTML> diff --git a/doc/gran_cohesion_washino_capillary_viscous.txt b/doc/gran_cohesion_washino_capillary_viscous.txt index 513350a2c0972018da91011527caf13db4185b37..335b4d19f0cbec2099ef0caaa9af2a9b89d78583 100644 --- a/doc/gran_cohesion_washino_capillary_viscous.txt +++ b/doc/gran_cohesion_washino_capillary_viscous.txt @@ -6,11 +6,21 @@ :line -gran cohesion washino/capillary/viscous :h3 +gran cohesion washino/capillary/viscous command :h3 [Syntax:] -cohesion washino/capillary/viscous :pre +cohesion washino/capillary/viscous \[other model_type/model_name pairs as described "here"_pair_gran.html \] keyword values :pre +zero or more keyword/value pairs may be appended to the end (after all models are specified) :l + {limitLiquidContent} values = 'on' or 'off' + on = enables the model parameter {maxLiquidContent} + off = standard implementation without a limiter for the per particle liquid content + {modifyLbVolume} values = 'on' or 'off' + on = enables the model parameter {lbVolumeFraction} + off = standard implementation with lbVolumeFraction = 0.05 + {tangential_reduce} values = 'on' or 'off' + on = tangential model does not see normal force computed by this model + off = tangential model does see normal force computed by this model :pre [Description:] @@ -24,7 +34,9 @@ to the liquid bridge force, i.e. {radius}*{maxSeparationDistanceRatio} is the effective contact radius of the particles. The model parameter {maxLiquidContent} allows to limit the maximum per particle -liquid content. +liquid content. (enabled by keyword {limitLiquidContent}) + +The model parameter {lbVolumeFraction} defines the amout of liquid that formes the liquid bridge with a neighbouring particle. (enabled by the keyword {modifyLbVolume}) :line @@ -32,7 +44,7 @@ Bridge formation and break-up, surface liquid transfer: {Vbond}, the volume of surface liquid involved in the bridge, is given by -Vbond = 0.05*(surfaceLiquidVolI+surfaceLiquidVolJ) :pre +Vbond = lbVolumeFraction * (surfaceLiquidVolI+surfaceLiquidVolJ) :pre where {surfaceLiquidVolI/J} is the surface liquid volume attached to particle i/j. This model assumes that both formation distance and rupture distance @@ -113,6 +125,13 @@ fix id all property/global contactAngle peratomtype value_1 value_2 ... fix id all property/global maxLiquidContent peratomtype value_1 value_2 ... (value_i=value for contact angle of atom type i and fluid) :pre +The optional keyword {tangential_reduce} defines if the tangential force model should +"see" the additional normal force excerted by this model. If it is 'off' (which is default) +then the tangential force model will be able to transmit a larger amount of tangential force +If {tangential_reduce} = 'on' then the tangential model will not take the normal force +from this model into account, typically leading to a lower value of tangential force +(via the Coulomb friction limit) + [Output:] This gran model stores a couple of per-particle properties, for access @@ -134,6 +153,10 @@ of a "fix wall/gran"_fix_wall_gran.html. The cohesion model is not available for "atom_style"_atom_style.html superquadric +[Default:] + +lbVolumeFraction = 0.05 + [References:] :link(Lian) @@ -146,3 +169,6 @@ The cohesion model is not available for "atom_style"_atom_style.html superquadri [(Rabinovitch)] Rabinovitch, Esayanur, Moudil, Langmuir, p10992, 21 (2005) +[Default:] + +{tangential_reduce} = 'off' diff --git a/doc/gran_model_hertz.html b/doc/gran_model_hertz.html index 35b97d6c45f359d88d86d62630c57a3dbcd6495f..63a88cc6e160beea8a7e04e128370668a85e4189 100644 --- a/doc/gran_model_hertz.html +++ b/doc/gran_model_hertz.html @@ -9,7 +9,7 @@ <HR> -<H3>gran model hertz +<H3>gran model hertz command </H3> <P><B>Syntax:</B> </P> @@ -92,7 +92,7 @@ fix id all property/global coefficientFriction peratomtypepair n_atomtypes value </P> <P>This model contributes to surface heating in the frame of <A HREF = "gran_surface_sphere_heatable.html">surface sphere/heatable</A> if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). </P> <P><B>Force Limiting:</B> </P> diff --git a/doc/gran_model_hertz.txt b/doc/gran_model_hertz.txt index 9aec52548ff01551fa2c5ac023a672cb739f6e97..0e389bf2cd2db9da72dbd978f786283c37ec297f 100644 --- a/doc/gran_model_hertz.txt +++ b/doc/gran_model_hertz.txt @@ -6,7 +6,7 @@ :line -gran model hertz :h3 +gran model hertz command :h3 [Syntax:] @@ -76,7 +76,7 @@ IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... This model contributes to surface heating in the frame of "surface sphere/heatable"_gran_surface_sphere_heatable.html if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). [Force Limiting:] diff --git a/doc/gran_model_hertz_stiffness.html b/doc/gran_model_hertz_stiffness.html index 58b30ebbaed075286f4b77683b04865a3ec9eaff..56d651aef9b89b4120ba216463f013d45aa0f16b 100644 --- a/doc/gran_model_hertz_stiffness.html +++ b/doc/gran_model_hertz_stiffness.html @@ -9,7 +9,7 @@ <HR> -<H3>gran model hertz/stiffness +<H3>gran model hertz/stiffness command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_model_hertz_stiffness.txt b/doc/gran_model_hertz_stiffness.txt index 3cc475c6941ec98b28e214bd87fe4357811beec8..ec4ba575c66dea18b719e6df6eb0a45ad9535f75 100644 --- a/doc/gran_model_hertz_stiffness.txt +++ b/doc/gran_model_hertz_stiffness.txt @@ -6,7 +6,7 @@ :line -gran model hertz/stiffness :h3 +gran model hertz/stiffness command :h3 [Syntax:] diff --git a/doc/gran_model_hooke.html b/doc/gran_model_hooke.html index cdd9dc72cb2c22a742871ebcbfbbaae1e2babe96..6f86fb3780305788bb410dba859ce47750eb4819 100644 --- a/doc/gran_model_hooke.html +++ b/doc/gran_model_hooke.html @@ -9,7 +9,7 @@ <HR> -<H3>gran model hooke +<H3>gran model hooke command </H3> <P><B>Syntax:</B> </P> @@ -128,7 +128,7 @@ fix id all property/global MaximumRestitution peratomtypepair n_atomtypes value_ </P> <P>This model contributes to surface heating in the frame of <A HREF = "gran_surface_sphere_heatable.html">surface sphere/heatable</A> if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). </P> <P><B>Restrictions:</B> </P> diff --git a/doc/gran_model_hooke.txt b/doc/gran_model_hooke.txt index 19ed8d6389ab98b460d6a716c2ddf8009becf4ac..5ef16ee857412c32fe096b2c0a855248a8010c58 100644 --- a/doc/gran_model_hooke.txt +++ b/doc/gran_model_hooke.txt @@ -6,7 +6,7 @@ :line -gran model hooke :h3 +gran model hooke command :h3 [Syntax:] @@ -112,7 +112,7 @@ IMPORTANT NOTE: You have to use atom styles beginning from 1, e.g. 1,2,3,... This model contributes to surface heating in the frame of "surface sphere/heatable"_gran_surface_sphere_heatable.html if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). [Restrictions:] diff --git a/doc/gran_model_hooke_stiffness.html b/doc/gran_model_hooke_stiffness.html index a737fe916f7a3d3ebcb251959fb740a53180a453..fae0c58989b7c7bee75c6375ef4473292a1e0136 100644 --- a/doc/gran_model_hooke_stiffness.html +++ b/doc/gran_model_hooke_stiffness.html @@ -9,7 +9,7 @@ <HR> -<H3>gran model hooke/stiffness +<H3>gran model hooke/stiffness command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_model_hooke_stiffness.txt b/doc/gran_model_hooke_stiffness.txt index 0fa9fd8cc3b8b76e66e50eed16a4d036d5158d0e..9c7ee5100af28c275ebd6de720f821cdb011578c 100644 --- a/doc/gran_model_hooke_stiffness.txt +++ b/doc/gran_model_hooke_stiffness.txt @@ -6,7 +6,7 @@ :line -gran model hooke/stiffness :h3 +gran model hooke/stiffness command :h3 [Syntax:] diff --git a/doc/gran_rolling_friction_cdt.html b/doc/gran_rolling_friction_cdt.html index 0287d763de78cb03f21d198dfc82f1fd29287cd3..3dd3c0f847962f0d43eeca87510a3d7d85af653e 100644 --- a/doc/gran_rolling_friction_cdt.html +++ b/doc/gran_rolling_friction_cdt.html @@ -9,7 +9,7 @@ <HR> -<H3>gran rolling_friction cdt +<H3>gran rolling_friction cdt command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_rolling_friction_cdt.txt b/doc/gran_rolling_friction_cdt.txt index 9c1ca9443d80a3e60cd29c260f0e32b2b536435d..87c1040d80106fe6c3f1e78778343540fbb843c2 100644 --- a/doc/gran_rolling_friction_cdt.txt +++ b/doc/gran_rolling_friction_cdt.txt @@ -6,7 +6,7 @@ :line -gran rolling_friction cdt :h3 +gran rolling_friction cdt command :h3 [Syntax:] diff --git a/doc/gran_rolling_friction_epsd.html b/doc/gran_rolling_friction_epsd.html index 419b445069540ac3508a1a6741c2c4cd3046e6df..d1fffaac3afaf07307b49339aaa214642b2e8cec 100644 --- a/doc/gran_rolling_friction_epsd.html +++ b/doc/gran_rolling_friction_epsd.html @@ -9,7 +9,7 @@ <HR> -<H3>gran rolling_friction epsd +<H3>gran rolling_friction epsd command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_rolling_friction_epsd.txt b/doc/gran_rolling_friction_epsd.txt index 5fb2ca5bd1e31c6f3f9ad168de6f05c494fb3e2a..0e2b24e39e68f025d4347dbed41119a8b8174e56 100644 --- a/doc/gran_rolling_friction_epsd.txt +++ b/doc/gran_rolling_friction_epsd.txt @@ -6,7 +6,7 @@ :line -gran rolling_friction epsd :h3 +gran rolling_friction epsd command :h3 [Syntax:] diff --git a/doc/gran_rolling_friction_epsd2.html b/doc/gran_rolling_friction_epsd2.html index eb2ac8d76af94d0b8e6f590d8c92618ac8a9ac6b..57647298ece22c43b49a31097d4d4c4c5d19ae9a 100644 --- a/doc/gran_rolling_friction_epsd2.html +++ b/doc/gran_rolling_friction_epsd2.html @@ -9,7 +9,7 @@ <HR> -<H3>gran rolling_friction epsd2 +<H3>gran rolling_friction epsd2 command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_rolling_friction_epsd2.txt b/doc/gran_rolling_friction_epsd2.txt index d9c98fff7bc760995bd818d57865e24fea4d9de5..0149687ede705d15b6dd2550174e87a0e529672a 100644 --- a/doc/gran_rolling_friction_epsd2.txt +++ b/doc/gran_rolling_friction_epsd2.txt @@ -6,7 +6,7 @@ :line -gran rolling_friction epsd2 :h3 +gran rolling_friction epsd2 command :h3 [Syntax:] diff --git a/doc/gran_rolling_friction_epsd3.html b/doc/gran_rolling_friction_epsd3.html index ce3cf4c7e5ff4ff27040fe24cc78437048aa9ed0..5eed3344a87619a4327c4632537b28b65544c863 100644 --- a/doc/gran_rolling_friction_epsd3.html +++ b/doc/gran_rolling_friction_epsd3.html @@ -9,7 +9,7 @@ <HR> -<H3>gran rolling_friction epsd3 +<H3>gran rolling_friction epsd3 command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_rolling_friction_epsd3.txt b/doc/gran_rolling_friction_epsd3.txt index 67ab14a2d7bcc985e4ea6a428ad64954c1c9e991..b3e915ed8208f7cf05d108b4731e4501034857b7 100644 --- a/doc/gran_rolling_friction_epsd3.txt +++ b/doc/gran_rolling_friction_epsd3.txt @@ -6,7 +6,7 @@ :line -gran rolling_friction epsd3 :h3 +gran rolling_friction epsd3 command :h3 [Syntax:] diff --git a/doc/gran_surface_sphere.html b/doc/gran_surface_sphere.html index 7dbc0e7b3eec8d4294d37f4bef9ab09665582cbb..887e5003f64356b50c0ab9fc848e4b6558b9eafc 100644 --- a/doc/gran_surface_sphere.html +++ b/doc/gran_surface_sphere.html @@ -9,7 +9,7 @@ <HR> -<H3>gran surface sphere +<H3>gran surface sphere command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_surface_sphere.txt b/doc/gran_surface_sphere.txt index a31457995407053d08f5d8b32b62d61b70684d3e..02b3eb382dbcc91f65231d050804431fce101652 100644 --- a/doc/gran_surface_sphere.txt +++ b/doc/gran_surface_sphere.txt @@ -6,7 +6,7 @@ :line -gran surface sphere :h3 +gran surface sphere command :h3 [Syntax:] diff --git a/doc/gran_tangential_history.html b/doc/gran_tangential_history.html index 6c228f184c574f4504d7dc1bb72ad7b96ccf60ee..5ffed1afccbff152d5ab960d25e2f6259131b389 100644 --- a/doc/gran_tangential_history.html +++ b/doc/gran_tangential_history.html @@ -9,7 +9,7 @@ <HR> -<H3>gran tangential history +<H3>gran tangential history command </H3> <P><B>Syntax:</B> </P> @@ -48,7 +48,7 @@ i.e. the Coulomb criterion is not met. </P> <P>This model contributes to surface heating in the frame of <A HREF = "gran_surface_sphere_heatable.html">surface sphere/heatable</A> if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). </P> <P><B>Default:</B> </P> diff --git a/doc/gran_tangential_history.txt b/doc/gran_tangential_history.txt index fc5df788935b74315b00a19dfc4369c5c807d698..289ca37cf48dd6a2f712986361611f06cb6a1ac1 100644 --- a/doc/gran_tangential_history.txt +++ b/doc/gran_tangential_history.txt @@ -6,7 +6,7 @@ :line -gran tangential history :h3 +gran tangential history command :h3 [Syntax:] @@ -43,7 +43,7 @@ i.e. the Coulomb criterion is not met. This model contributes to surface heating in the frame of "surface sphere/heatable"_gran_surface_sphere_heatable.html if the -appropriate flag is activated +appropriate flag is activated (only available in the PREMIUM version). [Default:] diff --git a/doc/gran_tangential_no_history.html b/doc/gran_tangential_no_history.html index 693cc473f9191c1273eae49cb93ea83453fc7119..b7b1925b3b2a4777048969f62278e5fe472fc40c 100644 --- a/doc/gran_tangential_no_history.html +++ b/doc/gran_tangential_no_history.html @@ -9,7 +9,7 @@ <HR> -<H3>gran tangential no_history +<H3>gran tangential no_history command </H3> <P><B>Syntax:</B> </P> diff --git a/doc/gran_tangential_no_history.txt b/doc/gran_tangential_no_history.txt index c3c13f8603d76ad1f3cee6af4aee0d1ce826e0d1..21052cff4abfeea4415ba454a158a508c1c5da68 100644 --- a/doc/gran_tangential_no_history.txt +++ b/doc/gran_tangential_no_history.txt @@ -6,7 +6,7 @@ :line -gran tangential no_history :h3 +gran tangential no_history command :h3 [Syntax:] diff --git a/doc/install_liggghts_windows.html b/doc/install_liggghts_windows.html index c9b38794c158e53f860f498c3b46bc4e2180982c..567d3d58b9f8f83e81e19d7e464d89d0de078f8e 100644 --- a/doc/install_liggghts_windows.html +++ b/doc/install_liggghts_windows.html @@ -1,26 +1,10 @@ <HTML> -<CENTER><A HREF = "http://www.cfdem.com">CFDEMproject WWW Site</A> - <A HREF = "Manual.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> +<CENTER><A HREF = "http://www.cfdem.com">CFDEMproject WWW Site</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> </CENTER> - - - - - - - - - - - - - - - - <HR> @@ -41,10 +25,18 @@ </H5> <P>LIGGGHTS(R)-PUBLIC is a highly parallelized simulation engine. If you want to run simulations in parallel you have to install MPI (Message Passing Interface standard). We suggest to use the implementation of Microsoft, which is available <A HREF = "http://msdn.microsoft.com/en-us/library/bb524831%28v=vs.85%29.aspx">here</A>. You need the binaries and the header files (included in the SDK). Please follow the instructions of the installer. </P> + + <H5>Git: </H5> <P>GIT is an open-source version control system. We provide LIGGGHTS(R)-PUBLIC via <A HREF = "http://github.com">github</A>. It is to your advantage to use any git program to keep your LIGGGHTS(R)-PUBLIC version up-to-date. We recommend to use <A HREF = "http://git-scm.com">git-scm</A> as it provides a minimum bash environment too. </P> + + + + + + <P>You can set up your GIT environment to use the SSH-Keys thus you don't have to enter your user and password multiple times. Check the GIT GUI documentation for more details. </P> <P><B>Important: Git-scm will ask during installation how it should handle newlines; please use "Checkout as-is, commit Unix-style line endings".</B> @@ -53,10 +45,16 @@ </H5> <P>A python script updates the VS-project, thus you have to install either <A HREF = "https://www.python.org/downloads/windows/">python</A> or <A HREF = "https://www.cygwin.com/">cygwin</A>. In case of cygwin you can use another GIT program, because cygwin provides also a bash environment. The description of the procedure assumes that you have installed cygwin. </P> + + + + <H5>Visual studio: </H5> <P>To compile LIGGGHTS(R)-PUBLIC you need a development environment. You can download Microsoft Visual Studio Express (current version: Express 2013 with Update 4 for Windows Desktop) for free from <A HREF = "http://www.visualstudio.com">www.visualstudio.com</A>. Therefore, you have to create an Microsoft account. </P> + + <H5>VTK support: </H5> <P>A detailed description how to compile LIGGGHTS(R)-PUBLIC with VTK support will follow here. @@ -79,6 +77,8 @@ </H5> <P>In this tutorial we use the suggested <A HREF = "http://git-scm.com">git-scm</A>. You can use either the <I>Git GUI</I> or the <I>Git Bash</I>. In case of a bash you can follow the instructions in the documentation <A HREF = "githubAccess_non-public.html">githubAccess_non-public</A>. Otherwise copy the link to your repository, for instance <I>https://github.com/CFDEMproject/LIGGGHTS-COMPANY.git</I>, into the <I>Git GUI</I> and save the repository at your computer, e.g. <I>C:/repositories/LIGGGHTS-COMPANY</I>. </P> + + <P>In the directory <I>LIGGGHTS-COMPANY/src/WINDOWS</I> you find an README, which describes the following steps in detail. </P> <H5>Update auto-generated header-files: diff --git a/doc/install_liggghts_windows.txt b/doc/install_liggghts_windows.txt index 44c7536bd11e7e7d7747183e62b144268b985d7f..0e42314e705964ad2933277ec9e4aca2618b6f8b 100644 --- a/doc/install_liggghts_windows.txt +++ b/doc/install_liggghts_windows.txt @@ -1,16 +1,8 @@ -"CFDEMproject WWW Site"_lws - "LIGGGHTS(R)-PUBLIC Commands"_ll :c +"CFDEMproject WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Commands"_lc :c -:link(lws,http://www.cfdem.com) -:link(lc,CFDEMcoupling_Manual.html#comm) -:link(ll,Manual.html#comm) -:link(msmpi,http://msdn.microsoft.com/en-us/library/bb524831%28v=vs.85%29.aspx) -:link(github,http://github.com) -:link(gitHelp,http://help.github.com/linux-set-up-git) -:link(gitbash,http://git-scm.com) -:link(vs,http://www.visualstudio.com) -:link(python,https://www.python.org/downloads/windows/) -:link(cygwin,https://www.cygwin.com/) -:link(gitMan,githubAccess_non-public.html) +:link(liws,http://www.cfdem.com) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) :line Compile LIGGGHTS(R)-PUBLIC for Windows :h3 @@ -28,9 +20,15 @@ MPI: :h5 LIGGGHTS(R)-PUBLIC is a highly parallelized simulation engine. If you want to run simulations in parallel you have to install MPI (Message Passing Interface standard). We suggest to use the implementation of Microsoft, which is available "here"_msmpi. You need the binaries and the header files (included in the SDK). Please follow the instructions of the installer. +:link(msmpi,http://msdn.microsoft.com/en-us/library/bb524831%28v=vs.85%29.aspx) + Git: :h5 -GIT is an open-source version control system. We provide LIGGGHTS(R)-PUBLIC via "github"_github. It is to your advantage to use any git program to keep your LIGGGHTS(R)-PUBLIC version up-to-date. We recommend to use "git-scm"_gitbash as it provides a minimum bash environment too. +GIT is an open-source version control system. We provide LIGGGHTS(R)-PUBLIC via "github"_gitHub. It is to your advantage to use any git program to keep your LIGGGHTS(R)-PUBLIC version up-to-date. We recommend to use "git-scm"_gitbash as it provides a minimum bash environment too. + +:link(gitHub,http://github.com) +:link(gitHelp,http://help.github.com/linux-set-up-git) +:link(gitbash,http://git-scm.com) You can set up your GIT environment to use the SSH-Keys thus you don't have to enter your user and password multiple times. Check the GIT GUI documentation for more details. @@ -40,10 +38,15 @@ Python or Cygwin: :h5 A python script updates the VS-project, thus you have to install either "python"_python or "cygwin"_cygwin. In case of cygwin you can use another GIT program, because cygwin provides also a bash environment. The description of the procedure assumes that you have installed cygwin. +:link(python,https://www.python.org/downloads/windows/) +:link(cygwin,https://www.cygwin.com/) + Visual studio: :h5 To compile LIGGGHTS(R)-PUBLIC you need a development environment. You can download Microsoft Visual Studio Express (current version: Express 2013 with Update 4 for Windows Desktop) for free from "www.visualstudio.com"_vs. Therefore, you have to create an Microsoft account. +:link(vs,http://www.visualstudio.com) + VTK support: :h5 A detailed description how to compile LIGGGHTS(R)-PUBLIC with VTK support will follow here. @@ -52,7 +55,7 @@ Procedure: :h4 Basically the following steps have to be performed: -download/clone your repository from "github"_github :ulb,l +download/clone your repository from "github"_gitHub :ulb,l update auto-generated header-files :l update your VS-project :l compile your LIGGGHTS(R)-PUBLIC version :l @@ -62,6 +65,8 @@ Download/clone your LIGGGHTS(R)-PUBLIC version: :h5 In this tutorial we use the suggested "git-scm"_gitbash. You can use either the {Git GUI} or the {Git Bash}. In case of a bash you can follow the instructions in the documentation "githubAccess_non-public"_gitMan. Otherwise copy the link to your repository, for instance {https://github.com/CFDEMproject/LIGGGHTS-COMPANY.git}, into the {Git GUI} and save the repository at your computer, e.g. {C:/repositories/LIGGGHTS-COMPANY}. +:link(gitMan,githubAccess_non-public.html) + In the directory {LIGGGHTS-COMPANY/src/WINDOWS} you find an README, which describes the following steps in detail. Update auto-generated header-files: :h5 diff --git a/doc/pair_gran.html b/doc/pair_gran.html index 64aa843212eee5ad39b711fc1b7da6495968e2eb..9d780b65f289f327318aa95909d7e372b2fd0974 100644 --- a/doc/pair_gran.html +++ b/doc/pair_gran.html @@ -11,9 +11,17 @@ <H3>pair_style gran command </H3> +<H3>pair_style bubble command +</H3> +<H3>pair_style gran_bubble bubble command +</H3> <P><B>Syntax:</B> </P> -<PRE>pair_style model_type model_name model_keyword model_value +<PRE>pair_style gran model_type model_name model_keyword model_value +</PRE> +<PRE>pair_style bubble model_type model_name model_keyword model_value +</PRE> +<PRE>pair_style gran_bubble model_type model_name model_keyword model_value </PRE> <LI>zero or more model_type/model_name pairs may be appended. They must be appended in the following order (!) @@ -37,9 +45,13 @@ pair_style gran model hertz tangential no_history cohesion sjkr </PRE> <P><B>General description:</B> </P> -<P>The <I>gran</I> styles use the following formula for the frictional force between two granular -particles, when the distance r between two particles of radii Ri and Rj is less than their -contact distance d = Ri + Rj. Typically, there is no force between the particles when r > d. +<P>The <I>gran</I> styles imposes a force between two neighboring particles. Typically, there is +a force when the distance r between two particles of radii Ri and Rj is less than their +contact distance dist = Ri + Rj, and no force otherwise. Some models, such as cohesion +models, may impose a force also when the particle surfaces do not touch. This is documented +for those models specifically. +</P> +<P>The general form of a granular interaction can be written as: </P> <CENTER><IMG SRC = "Eqs/pair_gran_html_60b8ced2.png"> </CENTER> @@ -73,6 +85,14 @@ doc pages <A HREF = "Section_gran_models.html">here</A> cohesive or rolling friction forces. These are also described on separate doc pages <A HREF = "Section_gran_models.html">here</A> </P> +<P>The styles <I>bubble</I> and <I>gran_bubble</I> are aliases for <I>gran</I>, which can e.g. be used +for the modelling of systems with different phases using <A HREF = "pair_hybrid.html">pair hybrid</A>, where a +different set of interaction laws is used for each phase. An example would be +</P> +<PRE>pair_style hybrid gran model hertz tangential history & + bubble model hertz tangential off & + gran_bubble model hertz tangential off +</PRE> <P>IMPORTANT NOTE: The order of model keywords is important, you have to stick to the order as outlined in the "Syntax" section of this doc page. </P> diff --git a/doc/pair_gran.txt b/doc/pair_gran.txt index 51c0030bd5bde6225f906d219c2efec2e7309a8d..88575c285514d1e957f508744c2accdcc6e3bdcc 100644 --- a/doc/pair_gran.txt +++ b/doc/pair_gran.txt @@ -7,10 +7,14 @@ :line pair_style gran command :h3 +pair_style bubble command :h3 +pair_style gran_bubble bubble command :h3 [Syntax:] -pair_style model_type model_name model_keyword model_value :pre +pair_style gran model_type model_name model_keyword model_value :pre +pair_style bubble model_type model_name model_keyword model_value :pre +pair_style gran_bubble model_type model_name model_keyword model_value :pre zero or more model_type/model_name pairs may be appended. They must be appended in the following order (!) :l {model} values = described "here"_Section_gran_models.html @@ -30,9 +34,14 @@ pair_style gran model hertz tangential no_history cohesion sjkr :pre [General description:] -The {gran} styles use the following formula for the frictional force between two granular -particles, when the distance r between two particles of radii Ri and Rj is less than their -contact distance d = Ri + Rj. Typically, there is no force between the particles when r > d. +The {gran} styles imposes a force between two neighboring particles. Typically, there is +a force when the distance r between two particles of radii Ri and Rj is less than their +contact distance dist = Ri + Rj, and no force otherwise. Some models, such as cohesion +models, may impose a force also when the particle surfaces do not touch. This is documented +for those models specifically. + + +The general form of a granular interaction can be written as: :c,image(Eqs/pair_gran_html_60b8ced2.png) @@ -60,6 +69,14 @@ Also, other models may add additional forces or torques on the particles, such a cohesive or rolling friction forces. These are also described on separate doc pages "here"_Section_gran_models.html +The styles {bubble} and {gran_bubble} are aliases for {gran}, which can e.g. be used +for the modelling of systems with different phases using "pair hybrid"_pair_hybrid.html, where a +different set of interaction laws is used for each phase. An example would be + +pair_style hybrid gran model hertz tangential history & + bubble model hertz tangential off & + gran_bubble model hertz tangential off :pre + IMPORTANT NOTE: The order of model keywords is important, you have to stick to the order as outlined in the "Syntax" section of this doc page. diff --git a/doc/rerun.html b/doc/rerun.html deleted file mode 100644 index 2ad09520a93d9d46eb244a76cc27ef76a3c87f65..0000000000000000000000000000000000000000 --- a/doc/rerun.html +++ /dev/null @@ -1,201 +0,0 @@ -<HTML> -<CENTER><A HREF = "http://www.cfdem.com">LIGGGHTS(R)-PUBLIC WWW Site</A> - <A HREF = "Manual.html">LIGGGHTS(R)-PUBLIC Documentation</A> - <A HREF = "Section_commands.html#comm">LIGGGHTS(R)-PUBLIC Commands</A> -</CENTER> - - - - - - -<HR> - -<H3>rerun command -</H3> -<P><B>Syntax:</B> -</P> -<PRE>rerun file1 file2 ... keyword args ... -</PRE> -<UL><LI>file1,file2,... = dump file(s) to read - -<LI>one or more keywords may be appended, keyword <I>dump</I> must appear and be last - -<PRE>keyword = <I>first</I> or <I>last</I> or <I>every</I> or <I>skip</I> or <I>start</I> or <I>stop</I> or <I>dump</I> - <I>first</I> args = Nfirts - Nfirst = dump timestep to start on - <I>last</I> args = Nlast - Nlast = dumptimestep to stop on - <I>every</I> args = Nevery - Nevery = read snapshots matching every this many timesteps - <I>skip</I> args = Nskip - Nskip = read one out of every Nskip snapshots - <I>start</I> args = Nstart - Nstart = timestep on which pseudo run will start - <I>stop</I> args = Nstop - Nstop = timestep to which pseudo run will end - <I>dump</I> args = same as <A HREF = "read_dump.html">read_dump</A> command starting with its field arguments -</PRE> - -</UL> -<P><B>Examples:</B> -</P> -<PRE>rerun dump.file dump x y z vx vy vz -rerun dump1.txt dump2.txt first 10000 every 1000 dump x y z -rerun dump.vels dump x y z vx vy vz box yes format molfile lammpstrj -rerun dump.dcd dump x y z box no format molfile dcd -rerun ../run7/dump.file.gz skip 2 dump x y z box yes -</PRE> -<P><B>Description:</B> -</P> -<P>Perform a pseudo simulation run where atom information is read one -snapshot at a time from a dump file(s), and energies and forces are -computed on the snapshot to produce thermodynamic or other output. -</P> -<P>This can be useful in the following kinds of scenarios, after an -initial simulation produced the dump file: -</P> -<UL><LI>Compute the energy and forces of snapshot using a different potential. - - -<LI>Calculate one or more diagnostic quantities on the snapshots that -weren't computed in the initial run. These can also be computed with -settings not used in the initial run, e.g. computing an RDF via the -<A HREF = "compute.rdf.html">compute rdf</A> command with a longer cutoff than was -used initially. - -<LI>Calculate the portion of per-atom forces resulting from a subset of -the potential. E.g. compute only Coulombic forces. This can be done -by only defining only a Coulombic pair style in the rerun script. -Doing this in the original script would result in different (bad) -dynamics. -</UL> -<P>Conceptually, using the rerun command is like running an input script -that has a loop in it (see the <A HREF = "next.html">next</A> and <A HREF = "jump.html">jump</A> -commands). Each iteration of the loop reads one snapshot from the -dump file via the <A HREF = "read_dump.html">read_dump</A> command, sets the -timestep to the appropriate value, and then invokes a <A HREF = "run.html">run</A> -command for zero timesteps to simply compute energy and forces, and -any other <A HREF = "thermo_style.html">thermodynamic output</A> or diagnostic info -you have defined. This computation also invokes any fixes you have -defined that apply constraints to the system, such as <A HREF = "fix_shake.html">fix -shake</A> or <A HREF = "fix_indent.html">fix indent</A>. -</P> -<P>Note that a simulation box must already be defined before using the -rerun command. This can be done by the <A HREF = "create_box.html">create_box</A>, -<A HREF = "read_data.html">read_data</A>, or <A HREF = "read_restart.html">read_restart</A> -commands. -</P> -<P>Also note that reading per-atom information from dump snapshots is -limited to the atom coordinates, velocities and image flags as -explained in the <A HREF = "read_dump.html">read_dump</A> command. Other atom -properties, which may be necessary to compute energies and forces, -such as atom charge, or bond topology information for a molecular -system, are not read from (or even contained in) dump files. Thus -this auxiliary information should be defined in the usual way, e.g. in -a data file read in by a <A HREF = "read_data.html">read_data</A> command, before -using the rerun command. -</P> -<HR> - -<P>If more than one dump file is specified, the dump files are read one -after the other. It is assumed that snapshot timesteps will be in -ascending order. If a snapshot is encountered that is not in -ascending order, it will cause the rerun command to complete. -</P> -<P>The <I>first</I>, <I>last</I>, <I>every</I>, <I>skip</I> keywords determine which -snapshots are read from the dump file(s). Snapshots are skipped until -they have a timestamp >= <I>Nfirst</I>. When a snapshot with a timestamp > -<I>Nlast</I> is encountered, the rerun command finishes. Note below that -the defaults for <I>first</I> and <I>last</I> are to read all snapshots. If the -<I>every</I> keyword is set to a value > 0, then only snapshots with -timestamps that are a multiple of <I>Nevery</I> are read (the first -snapshot is always read). If <I>Nevery</I> = 0, then this criterion is -ignored, i.e. every snapshot is read that meets the other criteria. -If the <I>skip</I> keyword is used, then after the first snapshot is read, -every Nth snapshot is read, where N = <I>Nskip</I>. E.g. if <I>Nskip</I> = 3, -then only 1 out of every 3 snapshots is read, assuming the snapshot -timestamp is also consistent with the other criteria. -</P> -<P>The <I>start</I> and <I>stop</I> keywords have the same meaning that they do for -the <A HREF = "run.html">run</A> command. They only need to be defined if (a) you -are using a <A HREF = "fix.html">fix</A> command that changes some value over time, -and (b) you want the reference point for elapsed time (from start to -stop) to be different than the <I>first</I> and <I>last</I> settings. See the -doc page for individual fixes to see which ones can be used with the -<I>start/stop</I> keywords. Note that if you define neither of the -<I>start</I>/<I>stop</I> or <I>first</I>/<I>last</I> keywords, then LIGGGHTS(R)-PUBLIC treats the -pseudo run as going from 0 to a huge value (effectively infinity). -This means that any quantity that a fix scales as a fraction of -elapsed time in the run, will essentially remain at its intiial value. -</P> -<P>The <I>dump</I> keyword is required and must be the last keyword specified. -Its arguments are passed internally to the <A HREF = "read_dump.html">read_dump</A> -command. The first argument following the <I>dump</I> keyword should be -the <I>field1</I> argument of the <A HREF = "read_dump.html">read_dump</A> command. See -the <A HREF = "read_dump.html">read_dump</A> doc page for details on the various -options it allows for extracting information from the dump file -snapshots, and for using that information to alter the LIGGGHTS(R)-PUBLIC -simulation. -</P> -<HR> - -<P>In general, a LIGGGHTS(R)-PUBLIC input script that uses a rerun command can -include and perform all the usual operations of an input script that -uses the <A HREF = "run.html">run</A> command. There are a few exceptions and -points to consider, as discussed here. -</P> -<P>Fixes that perform time integration, such as <A HREF = "fix_nve.html">fix nve</A> -are not invoked, since no time integration is performed. -</P> -<P>If you only want the rerun script to perform analyses that do not -involve pair interactions, such as use compute msd to calculated -displacements over time, you do not need to define a <A HREF = "pair_style.html">pair -style</A>, which may also mean neighbor lists will not -need to be calculated which saves time. The <A HREF = "communicate.html">communicate -cutoff</A> command can also be used to insure ghost -atoms are acquired from far enough away for operations like bond and -angle evaluations, if no pair style is being used. -</P> -<P>Every time a snapshot is read, the timestep for the simulation is -reset, as if the <A HREF = "reset_timestep.html<A HREF = "fix_deposit.html">>reset_timestep</A> command were -used. This command has some restrictions as to what fixes can be -defined. See its doc page for details. For example, the fix -deposit</A> and <A HREF = "fix_dt_reset.html">fix dt/reset</A> fixes -are in this category. They also make no sense to use with a rerun -command. -</P> -<P>If time-averaging fixes like <A HREF = "fix_ave_time.html">fix ave/time</A> are -used, they are invoked on timesteps that are a function of their -<I>Nevery</I>, <I>Nrepeat</I>, and <I>Nfreq</I> settings. As an example, see the -<A HREF = "fix_ave_time.html">fix ave/time</A> doc page for details. You must -insure those settings are consistent with the snapshot timestamps that -are read from the dump file(s). If an averaging fix is not invoked on -a timestep it expects to be, LIGGGHTS(R)-PUBLIC will flag an error. -</P> -<P>The various forms of LIGGGHTS(R)-PUBLIC output, as defined by the -<A HREF = "thermo_style.html">thermo_style</A>, <A HREF = "thermo.html">thermo</A>, -<A HREF = "dump.html">dump</A>, and <A HREF = "restart.html">restart</A> commands occur on -specific timesteps. If successvive dump snapshots skip those -timesteps, then no output will be produced. E.g. if you request -thermodynamic output every 100 steps, but the dump file snapshots are -every 1000 steps, then you will only see thermodynamic output every -1000 steps. -</P> -<HR> - -<P><B>Restrictions:</B> -</P> -<P>To read gzipped dump files, you must compile LIGGGHTS(R)-PUBLIC with the --DLAMMPS_GZIP option - see the <A HREF = "Section_start.html#start_2">Making -LIGGGHTS(R)-PUBLIC</A> section of the documentation. -</P> -<P><B>Related commands:</B> -</P> -<P><A HREF = "read_dump.html">read_dump</A> -</P> -<P><B>Default:</B> -</P> -<P>The option defaults are first = 0, last = a huge value (effectively -infinity), start = same as first, stop = same as last, every = 0, skip -= 1; -</P> -</HTML> diff --git a/doc/rerun.txt b/doc/rerun.txt deleted file mode 100644 index 5b5d96b0fac67cf844a85c093ba0f54b844ed1b6..0000000000000000000000000000000000000000 --- a/doc/rerun.txt +++ /dev/null @@ -1,193 +0,0 @@ -"LIGGGHTS(R)-PUBLIC WWW Site"_liws - "LIGGGHTS(R)-PUBLIC Documentation"_ld - "LIGGGHTS(R)-PUBLIC Commands"_lc :c - -:link(liws,http://www.cfdem.com) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -rerun command :h3 - -[Syntax:] - -rerun file1 file2 ... keyword args ... :pre - -file1,file2,... = dump file(s) to read :ulb,l -one or more keywords may be appended, keyword {dump} must appear and be last :l -keyword = {first} or {last} or {every} or {skip} or {start} or {stop} or {dump} - {first} args = Nfirts - Nfirst = dump timestep to start on - {last} args = Nlast - Nlast = dumptimestep to stop on - {every} args = Nevery - Nevery = read snapshots matching every this many timesteps - {skip} args = Nskip - Nskip = read one out of every Nskip snapshots - {start} args = Nstart - Nstart = timestep on which pseudo run will start - {stop} args = Nstop - Nstop = timestep to which pseudo run will end - {dump} args = same as "read_dump"_read_dump.html command starting with its field arguments :pre -:ule - -[Examples:] - -rerun dump.file dump x y z vx vy vz -rerun dump1.txt dump2.txt first 10000 every 1000 dump x y z -rerun dump.vels dump x y z vx vy vz box yes format molfile lammpstrj -rerun dump.dcd dump x y z box no format molfile dcd -rerun ../run7/dump.file.gz skip 2 dump x y z box yes :pre - -[Description:] - -Perform a pseudo simulation run where atom information is read one -snapshot at a time from a dump file(s), and energies and forces are -computed on the snapshot to produce thermodynamic or other output. - -This can be useful in the following kinds of scenarios, after an -initial simulation produced the dump file: - -Compute the energy and forces of snapshot using a different potential. -:ulb,l - -Calculate one or more diagnostic quantities on the snapshots that -weren't computed in the initial run. These can also be computed with -settings not used in the initial run, e.g. computing an RDF via the -"compute rdf"_compute.rdf.html command with a longer cutoff than was -used initially. :l - -Calculate the portion of per-atom forces resulting from a subset of -the potential. E.g. compute only Coulombic forces. This can be done -by only defining only a Coulombic pair style in the rerun script. -Doing this in the original script would result in different (bad) -dynamics. :l,ule - -Conceptually, using the rerun command is like running an input script -that has a loop in it (see the "next"_next.html and "jump"_jump.html -commands). Each iteration of the loop reads one snapshot from the -dump file via the "read_dump"_read_dump.html command, sets the -timestep to the appropriate value, and then invokes a "run"_run.html -command for zero timesteps to simply compute energy and forces, and -any other "thermodynamic output"_thermo_style.html or diagnostic info -you have defined. This computation also invokes any fixes you have -defined that apply constraints to the system, such as "fix -shake"_fix_shake.html or "fix indent"_fix_indent.html. - -Note that a simulation box must already be defined before using the -rerun command. This can be done by the "create_box"_create_box.html, -"read_data"_read_data.html, or "read_restart"_read_restart.html -commands. - -Also note that reading per-atom information from dump snapshots is -limited to the atom coordinates, velocities and image flags as -explained in the "read_dump"_read_dump.html command. Other atom -properties, which may be necessary to compute energies and forces, -such as atom charge, or bond topology information for a molecular -system, are not read from (or even contained in) dump files. Thus -this auxiliary information should be defined in the usual way, e.g. in -a data file read in by a "read_data"_read_data.html command, before -using the rerun command. - -:line - -If more than one dump file is specified, the dump files are read one -after the other. It is assumed that snapshot timesteps will be in -ascending order. If a snapshot is encountered that is not in -ascending order, it will cause the rerun command to complete. - -The {first}, {last}, {every}, {skip} keywords determine which -snapshots are read from the dump file(s). Snapshots are skipped until -they have a timestamp >= {Nfirst}. When a snapshot with a timestamp > -{Nlast} is encountered, the rerun command finishes. Note below that -the defaults for {first} and {last} are to read all snapshots. If the -{every} keyword is set to a value > 0, then only snapshots with -timestamps that are a multiple of {Nevery} are read (the first -snapshot is always read). If {Nevery} = 0, then this criterion is -ignored, i.e. every snapshot is read that meets the other criteria. -If the {skip} keyword is used, then after the first snapshot is read, -every Nth snapshot is read, where N = {Nskip}. E.g. if {Nskip} = 3, -then only 1 out of every 3 snapshots is read, assuming the snapshot -timestamp is also consistent with the other criteria. - -The {start} and {stop} keywords have the same meaning that they do for -the "run"_run.html command. They only need to be defined if (a) you -are using a "fix"_fix.html command that changes some value over time, -and (b) you want the reference point for elapsed time (from start to -stop) to be different than the {first} and {last} settings. See the -doc page for individual fixes to see which ones can be used with the -{start/stop} keywords. Note that if you define neither of the -{start}/{stop} or {first}/{last} keywords, then LIGGGHTS(R)-PUBLIC treats the -pseudo run as going from 0 to a huge value (effectively infinity). -This means that any quantity that a fix scales as a fraction of -elapsed time in the run, will essentially remain at its intiial value. - -The {dump} keyword is required and must be the last keyword specified. -Its arguments are passed internally to the "read_dump"_read_dump.html -command. The first argument following the {dump} keyword should be -the {field1} argument of the "read_dump"_read_dump.html command. See -the "read_dump"_read_dump.html doc page for details on the various -options it allows for extracting information from the dump file -snapshots, and for using that information to alter the LIGGGHTS(R)-PUBLIC -simulation. - -:line - -In general, a LIGGGHTS(R)-PUBLIC input script that uses a rerun command can -include and perform all the usual operations of an input script that -uses the "run"_run.html command. There are a few exceptions and -points to consider, as discussed here. - -Fixes that perform time integration, such as "fix nve"_fix_nve.html -are not invoked, since no time integration is performed. - -If you only want the rerun script to perform analyses that do not -involve pair interactions, such as use compute msd to calculated -displacements over time, you do not need to define a "pair -style"_pair_style.html, which may also mean neighbor lists will not -need to be calculated which saves time. The "communicate -cutoff"_communicate.html command can also be used to insure ghost -atoms are acquired from far enough away for operations like bond and -angle evaluations, if no pair style is being used. - -Every time a snapshot is read, the timestep for the simulation is -reset, as if the "reset_timestep"_reset_timestep.html command were -used. This command has some restrictions as to what fixes can be -defined. See its doc page for details. For example, the fix -deposit"_fix_deposit.html and "fix dt/reset"_fix_dt_reset.html fixes -are in this category. They also make no sense to use with a rerun -command. - -If time-averaging fixes like "fix ave/time"_fix_ave_time.html are -used, they are invoked on timesteps that are a function of their -{Nevery}, {Nrepeat}, and {Nfreq} settings. As an example, see the -"fix ave/time"_fix_ave_time.html doc page for details. You must -insure those settings are consistent with the snapshot timestamps that -are read from the dump file(s). If an averaging fix is not invoked on -a timestep it expects to be, LIGGGHTS(R)-PUBLIC will flag an error. - -The various forms of LIGGGHTS(R)-PUBLIC output, as defined by the -"thermo_style"_thermo_style.html, "thermo"_thermo.html, -"dump"_dump.html, and "restart"_restart.html commands occur on -specific timesteps. If successvive dump snapshots skip those -timesteps, then no output will be produced. E.g. if you request -thermodynamic output every 100 steps, but the dump file snapshots are -every 1000 steps, then you will only see thermodynamic output every -1000 steps. - -:line - -[Restrictions:] - -To read gzipped dump files, you must compile LIGGGHTS(R)-PUBLIC with the --DLAMMPS_GZIP option - see the "Making -LIGGGHTS(R)-PUBLIC"_Section_start.html#start_2 section of the documentation. - -[Related commands:] - -"read_dump"_read_dump.html - -[Default:] - -The option defaults are first = 0, last = a huge value (effectively -infinity), start = same as first, stop = same as last, every = 0, skip -= 1; diff --git a/doc/set.html b/doc/set.html index 742f40a9e7f7cbcd06ea8e8c573f2385e432fa0b..2f54b700cc6720d1f1c5b0ba707de3d5895472a2 100644 --- a/doc/set.html +++ b/doc/set.html @@ -34,6 +34,10 @@ value can be an atom-style variable (see below) <I>x</I>,<I>y</I>,<I>z</I> value = atom coordinate (distance units) value can be an atom-style variable (see below) + <I>vx</I>,<I>vy</I>,<I>vz</I> value = atom velocity (velocity units) + value can be an atom-style variable (see below) + <I>omegax</I>,<I>omegay</I>,<I>omegaz</I> value = atom rotational velocity (rad / time units) + value can be an atom-style variable (see below) <I>charge</I> value = atomic charge (charge units) value can be an atom-style variable (see below) <I>quat</I> values = a b c theta diff --git a/doc/set.txt b/doc/set.txt index 56b16171a3bf3af654953c5b05af02a0fbb8ea83..77f5031869080dd5050878cdaa1f79099f18bfe4 100644 --- a/doc/set.txt +++ b/doc/set.txt @@ -31,6 +31,10 @@ keyword = {type} or {type/fraction} or {mol} or {x} or {y} or {z} or \ value can be an atom-style variable (see below) {x},{y},{z} value = atom coordinate (distance units) value can be an atom-style variable (see below) + {vx},{vy},{vz} value = atom velocity (velocity units) + value can be an atom-style variable (see below) + {omegax},{omegay},{omegaz} value = atom rotational velocity (rad / time units) + value can be an atom-style variable (see below) {charge} value = atomic charge (charge units) value can be an atom-style variable (see below) {quat} values = a b c theta diff --git a/examples/LIGGGHTS/Tutorials_public/ParScale/heatTransferBed_paScal/pascal/in.pascal b/examples/LIGGGHTS/Tutorials_public/ParScale/heatTransferBed_paScal/pascal/in.pascal index 2008a0f79fdfce14bc088eeb7d625a5600b030a1..951ed44f61f81bf88ddc9b1d135f016180410593 100644 --- a/examples/LIGGGHTS/Tutorials_public/ParScale/heatTransferBed_paScal/pascal/in.pascal +++ b/examples/LIGGGHTS/Tutorials_public/ParScale/heatTransferBed_paScal/pascal/in.pascal @@ -1,6 +1,6 @@ particle_mesh nGridPoints 10 -particle_data number_particles 800 #must be number of particles + 1! +particle_data number_particles 800 #coupling json myCoupling coupling liggghts diff --git a/src/MAKE/Makefile.g++_mingw64 b/src/MAKE/Makefile.g++_mingw64 new file mode 100644 index 0000000000000000000000000000000000000000..95c1d280b80a970f61492097e8f5a568c3073a90 --- /dev/null +++ b/src/MAKE/Makefile.g++_mingw64 @@ -0,0 +1,108 @@ +# g++ = RedHat Linux box, g++4, MPICH2, FFTW + +SHELL = /bin/sh + +# --------------------------------------------------------------------- +# compiler/linker settings +# specify flags and libraries needed for your compiler + +CC = g++ +CCFLAGS = -g -O -Wa,-mbig-obj -Wno-unused-result -funroll-loops -fstrict-aliasing -Wall # -Wunused +SHFLAGS = -fPIC +DEPFLAGS = -M + +LINK = g++ +LINKFLAGS = -g -O +LIB = +SIZE = size + +ARCHIVE = ar +ARFLAGS = -rc +SHLIBFLAGS = -shared + +# --------------------------------------------------------------------- +# LAMMPS-specific settings +# specify settings for LAMMPS features you will use +# if you change any -D setting, do full re-compile after "make clean" + +# LAMMPS ifdef settings, OPTIONAL +# see possible settings in doc/Section_start.html#2_2 (step 4) + +LMP_INC = -DLAMMPS_GZIP #-DLAMMPS_JPEG + +# MPI library, REQUIRED +# see discussion in doc/Section_start.html#2_2 (step 5) +# can point to dummy MPI library in src/STUBS as in Makefile.serial +# INC = path for mpi.h, MPI compiler settings +# PATH = path for MPI library +# LIB = name of MPI library + +MPI_INC = -I/c/Programs/OpenMPI_v1.6.1-x64/include -DOMPI_SKIP_MPICXX=1 #-DMPICH_SKIP_MPICXX +MPI_PATH = -L/c/Programs/OpenMPI_v1.6.1-x64/lib +MPI_LIB = -lmpi -lpthread #-lmpich -lmpl + +# FFT library, OPTIONAL +# see discussion in doc/Section_start.html#2_2 (step 6) +# can be left blank to use provided KISS FFT library +# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings +# PATH = path for FFT library +# LIB = name of FFT library + +FFT_INC = #-DFFT_FFTW +FFT_PATH = +FFT_LIB = #-lfftw + +# JPEG and/or PNG library, OPTIONAL +# see discussion in doc/Section_start.html#2_2 (step 7) +# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC +# INC = path(s) for jpeglib.h and/or png.h +# PATH = path(s) for JPEG library and/or PNG library +# LIB = name(s) of JPEG library and/or PNG library + +JPG_INC = +JPG_PATH = +JPG_LIB = #-ljpeg + +# --------------------------------------------------------------------- +# build rules and dependencies +# no need to edit this section + +include Makefile.package.settings +include Makefile.package + +EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) +EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) +EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) + +# Path to src files + +vpath %.cpp .. +vpath %.h .. + +# Link target + +$(EXE): $(OBJ) + $(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE).exe + $(SIZE) $(EXE).exe + +# Library targets + +lib: $(OBJ) + $(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ) + +shlib: $(OBJ) + $(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o $(EXE) \ + $(OBJ) $(EXTRA_LIB) $(LIB) + +# Compilation rules + +%.o:%.cpp + $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< + +%.d:%.cpp + $(CC) $(CCFLAGS) $(EXTRA_INC) $(DEPFLAGS) $< > $@ + +# Individual dependencies + +DEPENDS = $(OBJ:.o=.d) +sinclude $(DEPENDS) diff --git a/src/MAKE/Makefile.ubuntuVTK_debug b/src/MAKE/Makefile.ubuntuVTK_debug index 260776d6234ede12ad843a704aac7649c276b315..8aefb1688514ac4c7bc3223eff053d9f09aa2fc1 100644 --- a/src/MAKE/Makefile.ubuntuVTK_debug +++ b/src/MAKE/Makefile.ubuntuVTK_debug @@ -7,13 +7,13 @@ SHELL = /bin/sh # specify flags and libraries needed for your compiler CC = mpic++ -CCFLAGS = -g -Og \ - -funroll-loops -fstrict-aliasing -Wall -Wno-unused-result -pg +CCFLAGS = -g -O2 \ + -funroll-loops -fstrict-aliasing -Wall -Wextra -Wno-uninitialized -pg SHFLAGS = DEPFLAGS = -M LINK = mpic++ -LINKFLAGS = -Og -pg +LINKFLAGS = -O2 -pg LIB = -lstdc++ SIZE = size diff --git a/src/PASCAL/Install.sh b/src/PASCAL/Install.sh index 0aa335edbaca39a7661074df7e69d7165457d236..459ccd1dc80a6d9c839525414aa72a64ad82001c 100755 --- a/src/PASCAL/Install.sh +++ b/src/PASCAL/Install.sh @@ -41,10 +41,15 @@ if (test $1 = 1) then sed -i -e 's/[^ \t]*Qt5[^ \t]* //' ../Makefile.package sed -i -e 's/[^ \t]*hdf5[^ \t]* //g' ../Makefile.package # global sed -i -e 's/[^ \t]*boost[^ \t]* //' ../Makefile.package - # add new paths + # add new paths - check if ParScale Requires HDF5 for successful linking sed -i -e 's|^PKG_INC =[ \t]*|&-I$(PASCAL_SRC_DIR) |' ../Makefile.package + if (test "$PASCAL_HDF5_DIR" = "") then + sed -i -e 's|^PKG_PATH =[ \t]*|&-L$(PASCAL_SRC_DIR) -L$(PASCAL_INST_DIR)/lib64 -L$(PASCAL_INST_DIR)/lib -L$(PASCAL_QT5_DIR)/lib -L$(PASCAL_THIRDPARTY_DIR)/chemkinReader/src |' ../Makefile.package + sed -i -e 's|^PKG_LIB =[ \t]*|&-l$(PASCAL_LIB_NAME) -lsundials_cvode -lsundials_nvecserial -lQt5Core -lchemkinreader -lboost_regex |' ../Makefile.package + else sed -i -e 's|^PKG_PATH =[ \t]*|&-L$(PASCAL_SRC_DIR) -L$(PASCAL_INST_DIR)/lib64 -L$(PASCAL_INST_DIR)/lib -L$(PASCAL_QT5_DIR)/lib -L$(PASCAL_HDF5_DIR)/lib -L$(PASCAL_HDF5_DIR)/lib64 -L$(PASCAL_THIRDPARTY_DIR)/chemkinReader/src |' ../Makefile.package sed -i -e 's|^PKG_LIB =[ \t]*|&-l$(PASCAL_LIB_NAME) -lsundials_cvode -lsundials_nvecserial -lQt5Core -lhdf5 -lhdf5_hl -lhdf5_cpp -lchemkinreader -lboost_regex |' ../Makefile.package + fi fi # if (test -e ../Makefile.package.settings) then diff --git a/src/abstract_mesh.h b/src/abstract_mesh.h index f761decb2a3a93fe0ccbf7fc2a870ffe485a1549..65a193cfbf23b13e481e64b9602abb3d36450ba9 100644 --- a/src/abstract_mesh.h +++ b/src/abstract_mesh.h @@ -58,6 +58,8 @@ namespace LAMMPS_NS virtual void setPrecision(double _precision) = 0; + virtual void setMinFeatureLength(double _min_feature_length) = 0; + virtual void setElementExclusionList(FILE *_file) = 0; virtual void autoRemoveDuplicates() = 0; diff --git a/src/associative_pointer_array.h b/src/associative_pointer_array.h index 0a249d7f857bccc575c18ea35bc44c28f0aded63..5591ab76de183ada1a4a4a4a1a86648bed38e816 100644 --- a/src/associative_pointer_array.h +++ b/src/associative_pointer_array.h @@ -45,6 +45,7 @@ #define LMP_ASSOCIATIVE_POINTER_ARRAY_H #include <string.h> +#include <algorithm> #include "memory.h" namespace LAMMPS_NS @@ -73,8 +74,6 @@ class AssociativePointerArray T* getBasePointerByIndex(int i) const; - void grow(int to); - int size() const; bool sameLength(int _len); @@ -83,6 +82,7 @@ class AssociativePointerArray inline void addUninitializedElement(); inline void addZeroElement(); inline void deleteAllElements(); + inline void deleteRestart(bool scale,bool translate,bool rotate); inline void deleteElement(int n); inline void deleteForwardElement(int n,bool scale,bool translate,bool rotate); inline void deleteRestartElement(int n,bool scale,bool translate,bool rotate); @@ -90,7 +90,8 @@ class AssociativePointerArray inline void clearReverse(bool scale,bool translate,bool rotate); - inline bool calcStatistics(double weighting_factor); + inline bool calcStatistics(); + inline int maxStatLevel() const; inline void storeOrig(class AssociativePointerArray &orig); inline void storeOrig(const char *_id,class AssociativePointerArray &orig); diff --git a/src/associative_pointer_array_I.h b/src/associative_pointer_array_I.h index 832525cb5410cc818bcf0bddbafdc05543eda618..565486156a57c93f9d835e9bc441fa6076306594 100644 --- a/src/associative_pointer_array_I.h +++ b/src/associative_pointer_array_I.h @@ -109,8 +109,11 @@ bool AssociativePointerArray<T>::sameLength(int _len) { for(int i = 0; i < numElem_; i++) + { + if(content_[i]->size() != _len) return false; + } return true; } @@ -182,18 +185,6 @@ // printf("%d %s %d\n",i,id_[i], strcmp(id_[i],"v")); } - template<typename T> - void AssociativePointerArray<T>::grow(int to) - { - int by; - for(int i = 0; i < maxElem_; i++) - { - by = to - getBasePointerByIndex(i)->size(); - if(by > 0) - getBasePointerByIndex(i)->addUninitialized(by); - } - } - template<typename T> int AssociativePointerArray<T>::size() const { @@ -234,7 +225,7 @@ } /* ---------------------------------------------------------------------- - delete element n + delete all elements in containers ------------------------------------------------------------------------- */ template<typename T> @@ -244,6 +235,17 @@ content_[i]->clearContainer(); } + /* ---------------------------------------------------------------------- + delete all restart elements in containers + ------------------------------------------------------------------------- */ + + template<typename T> + void AssociativePointerArray<T>::deleteRestart(bool scale,bool translate,bool rotate) + { + for(int i=0;i<numElem_;i++) + content_[i]->delRestart(scale,translate,rotate); + } + /* ---------------------------------------------------------------------- delete element n ------------------------------------------------------------------------- */ @@ -300,22 +302,44 @@ } /* ---------------------------------------------------------------------- - clear reverse properties, i.e. reset all of them to 0 + statistic functions ------------------------------------------------------------------------- */ template<typename T> - bool AssociativePointerArray<T>::calcStatistics(double weighting_factor) + bool AssociativePointerArray<T>::calcStatistics() { int ret = true; + const int maxLevel = maxStatLevel(); - for(int i=0;i<numElem_;i++) - if(content_[i]->isStatisticsContainer()) - ret = ret && content_[i]->calcStatistics(weighting_factor); + for(int j=1;j<=maxLevel;j++) + { + for(int i=0;i<numElem_;i++) + if( (content_[i]->getStatLevel() == j) && (content_[i]->isStatisticsContainer() && !(content_[i]->isScalingContainer()))) + ret = ret && content_[i]->calcStatistics(); + + for(int i=0;i<numElem_;i++) + if( (content_[i]->getStatLevel() == j) && (content_[i]->isStatisticsContainer() && content_[i]->isScalingContainer())) + ret = ret && content_[i]->updateScalingContainer(); + for(int i=0;i<numElem_;i++) + if( (content_[i]->getStatLevel() == j) && (content_[i]->isStatisticsContainer() && (!content_[i]->isScalingContainer()))) + ret = ret && content_[i]->normalizeStatistics(); + } // return false if any returns false return ret; } + template<typename T> + int AssociativePointerArray<T>::maxStatLevel() const + { + int maxLevel = 0; + + for(int i=0;i<numElem_;i++) + maxLevel = std::max(maxLevel, content_[i]->getStatLevel()); + + return maxLevel; + } + /* ---------------------------------------------------------------------- id 2 index ------------------------------------------------------------------------- */ diff --git a/src/atom.cpp b/src/atom.cpp index e17a95758ac017de540002e9f337beb50d21454b..6970cfabc5f05d4b2ae99310019459d33ee81cd3 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1685,6 +1685,10 @@ void *Atom::extract(const char *name,int &len) if (strcmp(name,"rmass") == 0) return (void *) rmass; if (strcmp(name,"vfrac") == 0) return (void *) vfrac; if (strcmp(name,"s0") == 0) return (void *) s0; + if (strcmp(name,"shape") == 0) return (void *) shape; + + len = 4; + if (strcmp(name,"quaternion") == 0) return (void *) quaternion; len = -1; return NULL; diff --git a/src/bounding_box.h b/src/bounding_box.h index 797136b573b5638710238784866cecaaebf4b5e0..ea814f78c12846acb2e2985cdb2b2d17783db8d0 100644 --- a/src/bounding_box.h +++ b/src/bounding_box.h @@ -113,6 +113,9 @@ class BoundingBox hi[2] = zHi; } + double getVolume() + { return (zHi-zLo)*(yHi-yLo)*(xHi-xLo); } + void getExtent(double extent[3]) const { extent[0] = xHi - xLo; extent[1] = yHi - yLo; diff --git a/src/cohesion_model_easo_capillary_viscous.h b/src/cohesion_model_easo_capillary_viscous.h index 0fced22bee04092b4b1d78a0cdf926cf5b09c7b2..6ffebddfe42de5a01534532f1e3e57e34b4f2b01 100644 --- a/src/cohesion_model_easo_capillary_viscous.h +++ b/src/cohesion_model_easo_capillary_viscous.h @@ -102,9 +102,13 @@ namespace ContactModels { error->all(FLERR,"Using cohesion model easo/capillary/viscous for walls is not supported"); } - void registerSettings(Settings&) {} + void registerSettings(Settings& settings) + { + settings.registerOnOff("tangential_reduce",tangentialReduce_,false); + } - void connectToProperties(PropertyRegistry & registry) { + void connectToProperties(PropertyRegistry & registry) + { registry.registerProperty("surfaceLiquidContentInitial", &MODEL_PARAMS::createliquidContentInitialEaso); registry.registerProperty("surfaceTension", &MODEL_PARAMS::createSurfaceTension); registry.registerProperty("fluidViscosity", &MODEL_PARAMS::createFluidViscosityEaso); @@ -172,6 +176,9 @@ namespace ContactModels { void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces) { + if(sidata.is_wall) + return; + const int i = sidata.j; const int j = sidata.j; const int itype = sidata.itype; @@ -227,7 +234,7 @@ namespace ContactModels { const double tor3 = sidata.en[0] * Ft2 - sidata.en[1] * Ft1; // add to fn, Ft - sidata.Fn += Fcapilary+FviscN; + if(tangentialReduce_) sidata.Fn += Fcapilary+FviscN; //sidata.Ft += ... // apply normal and tangential force @@ -265,6 +272,9 @@ namespace ContactModels { void surfacesClose(SurfacesCloseData & scdata, ForceData & i_forces, ForceData & j_forces) { + if(scdata.is_wall) + return; + double * const contflag = &scdata.contact_history[history_offset]; // 3 cases: (i) no bridge present, (ii) bridge active, (iii) bridge breaks this step @@ -396,7 +406,7 @@ namespace ContactModels { const double tor3 = enx * Ft2 - eny * Ft1; // add to fn, Ft - //scdata.Fn += Fcapilary+FviscN; + //if(tangentialReduce_) scdata.Fn += Fcapilary+FviscN; //scdata.Ft += ... // apply normal and tangential force @@ -464,6 +474,7 @@ namespace ContactModels { FixPropertyAtom *fix_surfaceliquidcontent; FixPropertyAtom *fix_liquidflux; FixScalarTransportEquation *fix_ste; + bool tangentialReduce_; }; } } diff --git a/src/cohesion_model_sjkr.h b/src/cohesion_model_sjkr.h index f42c327be82875e5acbf1c3808bce03f21045eb8..c8de4c82ff88c6ed4d9a602db15c54da0847bfbc 100644 --- a/src/cohesion_model_sjkr.h +++ b/src/cohesion_model_sjkr.h @@ -69,7 +69,10 @@ namespace ContactModels { } - void registerSettings(Settings&) {} + void registerSettings(Settings& settings) + { + settings.registerOnOff("tangential_reduce",tangentialReduce_,false); + } void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("cohEnergyDens", &MODEL_PARAMS::createCohesionEnergyDensity); @@ -93,7 +96,7 @@ namespace ContactModels { else Acont = - M_PI/4 * ( (r-ri-rj)*(r+ri-rj)*(r-ri+rj)*(r+ri+rj) )/(r*r); //contact area of the two spheres const double Fn_coh = -cohEnergyDens[sidata.itype][sidata.jtype]*Acont; - sidata.Fn += Fn_coh; + if(tangentialReduce_) sidata.Fn += Fn_coh; if(sidata.contact_flags) *sidata.contact_flags |= CONTACT_COHESION_MODEL; @@ -129,6 +132,7 @@ namespace ContactModels { private: double ** cohEnergyDens; + bool tangentialReduce_; }; } } diff --git a/src/cohesion_model_sjkr2.h b/src/cohesion_model_sjkr2.h index 4067acb09aa684f7b18ef344a84c4f4919d362de..149bad26588525db94189de48439631ef7eafdb4 100644 --- a/src/cohesion_model_sjkr2.h +++ b/src/cohesion_model_sjkr2.h @@ -69,7 +69,10 @@ namespace ContactModels { } - void registerSettings(Settings&) {} + void registerSettings(Settings& settings) + { + settings.registerOnOff("tangential_reduce",tangentialReduce_,false); + } void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("cohEnergyDens", &MODEL_PARAMS::createCohesionEnergyDensity); @@ -94,7 +97,7 @@ namespace ContactModels { Acont = M_PI * 2. * (2.*ri*rj/(ri+rj)) * (ri + rj - r); const double Fn_coh = -cohEnergyDens[sidata.itype][sidata.jtype]*Acont; - sidata.Fn += Fn_coh; + if(tangentialReduce_) sidata.Fn += Fn_coh; if(sidata.contact_flags) *sidata.contact_flags |= CONTACT_COHESION_MODEL; @@ -129,6 +132,7 @@ namespace ContactModels { private: double ** cohEnergyDens; + bool tangentialReduce_; }; } } diff --git a/src/cohesion_model_washino_capillary_viscous.h b/src/cohesion_model_washino_capillary_viscous.h index 557d4fc702f49d56d2ead3ae45b779ae80489407..e9b9b706a0b93a234d11fc8990ce23108d590a7b 100644 --- a/src/cohesion_model_washino_capillary_viscous.h +++ b/src/cohesion_model_washino_capillary_viscous.h @@ -83,6 +83,11 @@ namespace MODEL_PARAMS return createPerTypeProperty(registry, "maxLiquidContent", caller, sanity_checks, 0.0, 1.0); } + inline static ScalarProperty* createLbVolumeFraction(PropertyRegistry & registry, const char * caller, bool sanity_checks) + { + return createScalarProperty(registry, "lbVolumeFraction", caller, sanity_checks, 0.0, 1.0); + } + } namespace LIGGGHTS { @@ -100,7 +105,9 @@ namespace ContactModels { CohesionModel(LAMMPS * lmp, IContactHistorySetup * hsetup,class ContactModelBase *cmb) : Pointers(lmp), surfaceLiquidContentInitial(0.0), surfaceTension(0.0), contactAngle(0), minSeparationDistanceRatio(0.0), maxSeparationDistanceRatio(0.0), fluidViscosity(0.), - history_offset(0),fix_surfaceliquidcontent(0),fix_liquidflux(0), fix_ste(0), limit_lqc_flag_(false) + ln1overMinSeparationDistanceRatio(0.0), maxLiquidContent(0), volumeFraction(0.05), + history_offset(0),fix_surfaceliquidcontent(0),fix_liquidflux(0), fix_ste(0), limit_lqc_flag_(false), + mod_lb_vol_flag_(false) { history_offset = hsetup->add_history_value("contflag", "0"); @@ -108,13 +115,15 @@ namespace ContactModels { error->all(FLERR,"Using cohesion model washino/capillary/viscous for walls is not supported"); } - void registerSettings(Settings & settings) { + void registerSettings(Settings & settings) + { settings.registerOnOff("limitLiquidContent", limit_lqc_flag_, false); + settings.registerOnOff("modifyLbVolume", mod_lb_vol_flag_, false); + settings.registerOnOff("tangential_reduce",tangentialReduce_,false); } void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("surfaceLiquidContentInitial", &MODEL_PARAMS::createliquidContentInitialWashino); - registry.registerProperty("surfaceTension", &MODEL_PARAMS::createSurfaceTension); registry.registerProperty("fluidViscosity", &MODEL_PARAMS::createFluidViscosityWashino); registry.registerProperty("contactAngle", &MODEL_PARAMS::createContactAngle); @@ -137,6 +146,12 @@ namespace ContactModels { registry.connect("maxLiquidContent", maxLiquidContent, "cohesion_model washino/capillary/viscous"); } + // if mod_lb_vol_flag_ need additional property + if (mod_lb_vol_flag_) { + registry.registerProperty("lbVolumeFraction", &MODEL_PARAMS::createLbVolumeFraction); + registry.connect("lbVolumeFraction", volumeFraction, "cohesion_model washino/capillary/viscous"); + } + fix_ste = modify->find_fix_scalar_transport_equation("liquidtransfer"); if(!fix_ste) { @@ -188,6 +203,9 @@ namespace ContactModels { void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces) { + if(sidata.is_wall) + return; + const int i = sidata.j; const int j = sidata.j; const int itype = sidata.itype; @@ -213,7 +231,7 @@ namespace ContactModels { const double volLi1000 = /* 4/3 * 1000 */ 1333.333333*M_PI*radi*radi*radi*surfaceLiquidContent[i]; const double volLj1000 = /* 4/3 * 1000 */ 1333.333333*M_PI*radj*radj*radj*surfaceLiquidContent[j]; - const double volBond1000 = (volLi1000+volLj1000)*0.05; + const double volBond1000 = (volLi1000+volLj1000)*volumeFraction; // skip if bond volume too small if(volBond1000 < 1e-14) return; @@ -243,7 +261,7 @@ namespace ContactModels { const double tor3 = sidata.en[0] * Ft2 - sidata.en[1] * Ft1; // add to fn, Ft - sidata.Fn += Fcapilary+FviscN; + if(tangentialReduce_) sidata.Fn += Fcapilary+FviscN; //sidata.Ft += ... // apply normal and tangential force @@ -281,6 +299,9 @@ namespace ContactModels { void surfacesClose(SurfacesCloseData & scdata, ForceData & i_forces, ForceData & j_forces) { + if(scdata.is_wall) + return; + double * const contflag = &scdata.contact_history[history_offset]; // 3 cases: (i) no bridge present, (ii) bridge active, (iii) bridge breaks this step @@ -305,7 +326,7 @@ namespace ContactModels { const double volLi1000 = /* 4/3 * 1000 */ 1333.333333*M_PI*radi*radi*radi*surfaceLiquidContent[i]; const double volLj1000 = /* 4/3 * 1000*/ 1333.333333*M_PI*radj*radj*radj*surfaceLiquidContent[j]; - const double volBond1000 = (volLi1000+volLj1000)*0.05; + const double volBond1000 = (volLi1000+volLj1000)*volumeFraction; const double rEff = radi*radj / (radi+radj); const double contactAngleEff = 0.5 * contactAngle[itype] * contactAngle[jtype]; @@ -402,7 +423,7 @@ namespace ContactModels { const double tor3 = enx * Ft2 - eny * Ft1; // add to fn, Ft - //scdata.Fn += Fcapilary+FviscN; + //if(tangentialReduce_) scdata.Fn += Fcapilary+FviscN; //scdata.Ft += ... // apply normal and tangential force @@ -453,10 +474,10 @@ namespace ContactModels { const double invdt = 1./update->dt; // liquid flux is in vol% per time - liquidFlux[i] += invdt*(0.5 * volBond1000 - 0.05*volLi1000) / (1333.333333*M_PI*radi*radi*radi) ; + liquidFlux[i] += invdt*(0.5 * volBond1000 - volumeFraction*volLi1000) / (1333.333333*M_PI*radi*radi*radi) ; if (force->newton_pair || j < atom->nlocal) - liquidFlux[j] += invdt*(0.5 * volBond1000 - 0.05*volLj1000) / (1333.333333*M_PI*radj*radj*radj) ; + liquidFlux[j] += invdt*(0.5 * volBond1000 - volumeFraction*volLj1000) / (1333.333333*M_PI*radj*radj*radj) ; } // no else here, case (i) was already caught before @@ -478,12 +499,16 @@ namespace ContactModels { double surfaceLiquidContentInitial, surfaceTension, *contactAngle; double minSeparationDistanceRatio, maxSeparationDistanceRatio, fluidViscosity; double ln1overMinSeparationDistanceRatio, *maxLiquidContent; + double volumeFraction; int history_offset; FixPropertyAtom *fix_surfaceliquidcontent; FixPropertyAtom *fix_liquidflux; FixScalarTransportEquation *fix_ste; bool limit_lqc_flag_; + bool mod_lb_vol_flag_; + + bool tangentialReduce_; }; } } diff --git a/src/comm.h b/src/comm.h index 3e3cfae03954f1403766cd2cd382d029f47fefb7..03c1c2e566d13b1d0f308bf1ea4de06e10d55811 100644 --- a/src/comm.h +++ b/src/comm.h @@ -58,6 +58,8 @@ namespace LAMMPS_NS { class Comm : protected Pointers { + friend class Info; + public: int me,nprocs; // proc info int procgrid[3]; // procs assigned in each dim of 3d grid diff --git a/src/compute_ke.cpp b/src/compute_ke.cpp index 68cac1e5f40b9839edbc107a6d40c4b34c130172..8444887afa8c1c5cdfb5f481a4a91ca48bcdad07 100644 --- a/src/compute_ke.cpp +++ b/src/compute_ke.cpp @@ -104,5 +104,10 @@ double ComputeKE::compute_scalar() MPI_Allreduce(&ke,&scalar,1,MPI_DOUBLE,MPI_SUM,world); scalar *= pfactor; + + // for multispheres we need to get the kinetic energy from the multisphere fix + if (fix_ms) + scalar += fix_ms->extract_ke(); + return scalar; } diff --git a/src/compute_nparticles_tracer_region.cpp b/src/compute_nparticles_tracer_region.cpp index 1164e6a5c2fd06450e4a500a8d534d771cee3a68..8692ffbd6a2689b8ea9093c93c712795c2190386 100644 --- a/src/compute_nparticles_tracer_region.cpp +++ b/src/compute_nparticles_tracer_region.cpp @@ -250,7 +250,7 @@ void ComputeNparticlesTracerRegion::compute_vector_eval(bool countMass, double& else resultMarked += 1.0; - if(reset_marker_) + if(reset_marker_ && countMass) marker[i] = 0.0; } } diff --git a/src/compute_pair_gran_local.cpp b/src/compute_pair_gran_local.cpp index 447c59139b256100f243c07fbd961c254a9ebd4b..1da8190abf14f9830e71c73d151cec81ae392c1c 100644 --- a/src/compute_pair_gran_local.cpp +++ b/src/compute_pair_gran_local.cpp @@ -76,18 +76,17 @@ ComputePairGranLocal::ComputePairGranLocal(LAMMPS *lmp, int narg, char **arg) : array = NULL; // store everything by default expect heat flux - posflag = velflag = idflag = fflag = tflag = hflag = aflag = 1; + posflag = velflag = idflag = fflag = torqueflag = histflag = areaflag = 1; // do not store fn, ft, heat flux, delta by default - fnflag = ftflag = hfflag = dflag = 0; + fnflag = ftflag = deltaflag = heatflag = 0; //no extra distance for building the list of pairs - verbose =false; - extraSurfDistance = 0.0; + verbose = false; // if further args, store only the properties that are listed if(narg > 3) - posflag = velflag = idflag = fflag = tflag = hflag = aflag = dflag = 0; + posflag = velflag = idflag = fflag = fnflag = ftflag = torqueflag = histflag = areaflag = deltaflag = heatflag = 0; for (int iarg = 3; iarg < narg; iarg++) { @@ -98,14 +97,13 @@ ComputePairGranLocal::ComputePairGranLocal(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg],"force") == 0) fflag = 1; else if (strcmp(arg[iarg],"force_normal") == 0) fnflag = 1; else if (strcmp(arg[iarg],"force_tangential") == 0) ftflag = 1; - else if (strcmp(arg[iarg],"torque") == 0) tflag = 1; - else if (strcmp(arg[iarg],"history") == 0) hflag = 1; - else if (strcmp(arg[iarg],"contactArea") == 0) aflag = 1; - else if (strcmp(arg[iarg],"delta") == 0) dflag = 1; - else if (strcmp(arg[iarg],"heatFlux") == 0) hfflag = 1; - else if (strcmp(arg[iarg],"delta") == 0) hfflag = 1; + else if (strcmp(arg[iarg],"torque") == 0) torqueflag = 1; + else if (strcmp(arg[iarg],"history") == 0) histflag = 1; + else if (strcmp(arg[iarg],"contactArea") == 0) areaflag = 1; + else if (strcmp(arg[iarg],"delta") == 0) deltaflag = 1; + else if (strcmp(arg[iarg],"heatFlux") == 0) heatflag = 1; else if (strcmp(arg[iarg],"verbose") == 0) verbose = true; - else if (strcmp(arg[iarg],"extraSurfDistance") == 0) {extraSurfDistance = atof(arg[iarg+1]); iarg++;} + else if (strcmp(arg[iarg],"extraSurfDistance") == 0) error->all(FLERR,"this keyword is deprecated; neighbor->contactDistanceFactor is now used directly"); else if(0 == strcmp(style,"wall/gran/local") || 0 == strcmp(style,"pair/gran/local")) error->compute_error(FLERR,this,"illegal/unrecognized keyword"); } @@ -220,16 +218,19 @@ void ComputePairGranLocal::init_cpgl(bool requestflag) } // register heat transfer fix if applicable - if(hfflag) + if(heatflag) { for(ifix = 0; ifix < modify->nfix; ifix++) { - if(strcmp(modify->fix[ifix]->style,"heat/gran/conduction") == 0) + if( + (0 == strcmp(modify->fix[ifix]->style,"heat/gran")) || + (0 == strcmp(modify->fix[ifix]->style,"heat/gran/conduction")) + ) { fixheat = static_cast<FixHeatGranCond*>(modify->fix[ifix]); } } - if(!fixheat) error->warning(FLERR,"Compute pair/gran/local can not calculate heat flux values since no fix heat/gran/conduction not compute them"); + if(!fixheat) error->all(FLERR,"Compute pair/gran/local can not calculate heat flux values since no fix heat/gran/conduction not compute them"); // group of this compute and heat transfer fix must be same so same number of pairs is computed if(groupbit != fixheat->groupbit) error->all(FLERR,"Compute pair/gran/local group and fix heat/gran/conduction group cannot be different"); @@ -257,10 +258,10 @@ void ComputePairGranLocal::init_cpgl(bool requestflag) // at this point we know that ptr is valid reference_exists = 1; - if(hflag && dnum == 0) error->all(FLERR,"Compute pair/gran/local or wall/gran/local can not calculate history values since pair or wall style does not compute them"); + if(histflag && dnum == 0) error->all(FLERR,"Compute pair/gran/local or wall/gran/local can not calculate history values since pair or wall style does not compute them"); // standard values: pos1,pos2,id1,id2,extra id for mesh wall,force,torque,contact area - nvalues = posflag*6 + velflag*6 + idflag*3 + fflag*3 + fnflag*3 + ftflag*3 + tflag*3 + hflag*dnum + aflag + dflag + hfflag; + nvalues = posflag*6 + velflag*6 + idflag*3 + fflag*3 + fnflag*3 + ftflag*3 + torqueflag*3 + histflag*dnum + areaflag + deltaflag + heatflag; size_local_cols = nvalues; } @@ -290,13 +291,13 @@ void ComputePairGranLocal::compute_local() // count local entries and compute pair info - int nCountWithOverlap(0); - if(wall == 0) ncount = count_pairs(nCountWithOverlap); // # pairs is ensured to be the same for pair and heat - else ncount = count_wallcontacts(nCountWithOverlap); // # wall contacts ensured to be same for wall/gran and heat + int nCountSurfacesIntersect(0); + if(wall == 0) ncount = count_pairs(nCountSurfacesIntersect); // # pairs is ensured to be the same for pair and heat + else ncount = count_wallcontacts(nCountSurfacesIntersect); // # wall contacts ensured to be same for wall/gran and heat - //only consider rows with overlap (but allocate memory for all) + // only consider rows with overlap (but allocate memory for all) if (ncount > nmax) reallocate(ncount); - size_local_rows = nCountWithOverlap; + size_local_rows = nCountSurfacesIntersect; // get pair data if(wall == 0) @@ -325,7 +326,7 @@ void ComputePairGranLocal::compute_local() count pairs on this proc ------------------------------------------------------------------------- */ -int ComputePairGranLocal::count_pairs(int & nCountWithOverlap) +int ComputePairGranLocal::count_pairs(int & nCountSurfacesIntersect) { int i,j,m,n,ii,jj,inum,jnum; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; @@ -345,10 +346,12 @@ int ComputePairGranLocal::count_pairs(int & nCountWithOverlap) numneigh = list->numneigh; firstneigh = list->firstneigh; + double contactDistanceFactorSqr = (neighbor->contactDistanceFactor+1e-16) * (neighbor->contactDistanceFactor+1e-16); + // loop over neighbors of my atoms // skip if I or J are not in group - m = n = nCountWithOverlap = 0; + m = n = nCountSurfacesIntersect = 0; for (ii = 0; ii < inum; ii++) { i = ilist[ii]; if (!(mask[i] & groupbit)) continue; @@ -371,14 +374,15 @@ int ComputePairGranLocal::count_pairs(int & nCountWithOverlap) dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; - if (rsq < (radius[i]+radius[j])*(radius[i]+radius[j])) nCountWithOverlap++; - if (rsq >= (radius[i]+radius[j]+extraSurfDistance)*(radius[i]+radius[j]+extraSurfDistance)) continue; + + if (rsq < (radius[i]+radius[j])*(radius[i]+radius[j])) nCountSurfacesIntersect++; + if (rsq > (radius[i]+radius[j])*(radius[i]+radius[j])*contactDistanceFactorSqr) continue; m++; } } if(verbose) - printf("ComputePairGranLocal::count_pairs: detected %d pairs (extraSurfDistance: %g), and %d pairs with contact. \n", - m, extraSurfDistance, nCountWithOverlap); + printf("ComputePairGranLocal::count_pairs: detected %d pairs , and %d pairs with surface intersection. \n", + m, nCountSurfacesIntersect); return m; } @@ -390,6 +394,7 @@ int ComputePairGranLocal::count_wallcontacts(int & nCountWithOverlap) { // account for fix group // no distinction between ncount and nCountWithOverlap for now + nCountWithOverlap = fixwall->n_contacts_local(groupbit); return nCountWithOverlap; } @@ -400,6 +405,7 @@ int ComputePairGranLocal::count_wallcontacts(int & nCountWithOverlap) void ComputePairGranLocal::add_pair(int i,int j,double fx,double fy,double fz,double tor1,double tor2,double tor3,double *hist) { + double del[3],r,rsq,radi,radj,contactArea; double *xi,*xj,xi_w[3],xj_w[3],*vi,*vj; int nlocal; @@ -482,18 +488,18 @@ void ComputePairGranLocal::add_pair(int i,int j,double fx,double fy,double fz,do array[ipair][n++] = ft[1]; array[ipair][n++] = ft[2]; } - if(tflag) + if(torqueflag) { array[ipair][n++] = tor1; array[ipair][n++] = tor2; array[ipair][n++] = tor3; } - if(hflag) + if(histflag) { for(int d = 0; d < dnum; d++) array[ipair][n++] = hist[d]; } - if(aflag) + if(areaflag) { radi = atom->radius[i]; radj = atom->radius[j]; @@ -504,7 +510,7 @@ void ComputePairGranLocal::add_pair(int i,int j,double fx,double fy,double fz,do array[ipair][n++] = contactArea; } - if(dflag) + if(deltaflag) { radi = atom->radius[i]; radj = atom->radius[j]; @@ -518,13 +524,6 @@ void ComputePairGranLocal::add_pair(int i,int j,double fx,double fy,double fz,do /* ---------------------------------------------------------------------- */ -void ComputePairGranLocal::pair_finalize() -{ - ncount_added_via_pair = ipair; -} - -/* ---------------------------------------------------------------------- */ - void ComputePairGranLocal::add_heat(int i,int j,double hf) { if (newton_pair == 0 && j >= atom->nlocal && atom->tag[i] <= atom->tag[j]) return; @@ -532,7 +531,7 @@ void ComputePairGranLocal::add_heat(int i,int j,double hf) if (!(atom->mask[i] & groupbit)) return; if (!(atom->mask[j] & groupbit)) return; - if(hfflag) + if(heatflag) { // heat flux is always last value array[ipair][nvalues-1] = hf; @@ -544,6 +543,16 @@ void ComputePairGranLocal::add_heat(int i,int j,double hf) ipair++; } +/* ---------------------------------------------------------------------- */ + +void ComputePairGranLocal::pair_finalize() +{ + // ensure have the right number of entries - i.e. the # of sidata.hasforceupdate occurrancies! + + ncount_added_via_pair = ipair; + size_local_rows = ncount_added_via_pair; +} + /* ---------------------------------------------------------------------- add data from particle-wall contact on this proc ------------------------------------------------------------------------- */ @@ -681,24 +690,24 @@ void ComputePairGranLocal::add_wall_2(int i,double fx,double fy,double fz,double array[ipair][n-2] = ft[1]; array[ipair][n-1] = ft[2]; } - if(tflag) + if(torqueflag) { array[ipair][n++] = tor1; array[ipair][n++] = tor2; array[ipair][n++] = tor3; } - if(hflag) + if(histflag) { for(int d = 0; d < dnum; d++) array[ipair][n++] = hist[d]; } - if(aflag) + if(areaflag) { contactArea = (atom->radius[i]*atom->radius[i]-rsq)*M_PI; array[ipair][n++] = contactArea; } - if(dflag) + if(deltaflag) { array[ipair][n++] = atom->radius[i]-sqrt(rsq); @@ -715,13 +724,13 @@ void ComputePairGranLocal::add_heat_wall(int ip,double hf) { if (!(atom->mask[ip] & groupbit)) return; - if(hfflag) + if(heatflag) { // heat flux is always last value // use ipair -1 , add_heat_wall is not always called array[ipair-1][nvalues-1] = hf; } - else error->one(FLERR,"Illegal situation in ComputePairGranLocal::add_heat_wall"); + //else error->one(FLERR,"Illegal situation in ComputePairGranLocal::add_heat_wall"); } /* ---------------------------------------------------------------------- */ diff --git a/src/compute_pair_gran_local.h b/src/compute_pair_gran_local.h index 52ced4b067e2b145dbca11af77c199989416070f..4faf7958ad39bd5059cbd5c007d12e5d539b9d30 100644 --- a/src/compute_pair_gran_local.h +++ b/src/compute_pair_gran_local.h @@ -73,15 +73,71 @@ class ComputePairGranLocal : public Compute { virtual void add_heat_wall(int i,double hf); virtual void pair_finalize(); + + /* inline access */ + virtual bool decide_add(double *hist) { return true; } + inline int get_nvalues() + { return nvalues; } + + inline double** get_data() + { return array; } + + inline int get_ncount() + { return ncount_added_via_pair; } + + virtual int offset_x1() + { return (posflag > 0 ? 0 : -1); } + + virtual int offset_x2() + { return (posflag > 0 ? 3 : -1); } + + virtual int offset_v1() + { return (velflag > 0 ? posflag*6 : -1); } + + virtual int offset_v2() + { return (velflag > 0 ? posflag*6+3 : -1); } + + virtual int offset_id1() + { return (idflag > 0 ? posflag*6+velflag*6 : -1);} + + virtual int offset_id2() + { return (idflag > 0 ? posflag*6+velflag*6+1 : -1);} + + virtual int offset_f() + { return (fflag > 0 ? posflag*6+velflag*6+idflag*3 : -1);} + + virtual int offset_fn() + { return (fnflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3 : -1);} + + virtual int offset_ft() + { return (ftflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3 : -1);} + + virtual int offset_torque() + { return (torqueflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3+ftflag*3 : -1);} + + virtual int offset_history() + { return (histflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3+ftflag*3+torqueflag*3 : -1);} + + virtual int offset_area() + { return (areaflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3+ftflag*3+torqueflag*3+histflag*dnum : -1);} + + virtual int offset_delta() + { return (deltaflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3+ftflag*3+torqueflag*3+histflag*dnum+areaflag*1 : -1);} + + virtual int offset_heat() + { return (heatflag > 0 ? posflag*6+velflag*6+idflag*3+fflag*3+fnflag*3+ftflag*3+torqueflag*3+histflag*dnum+areaflag*1 + deltaflag*1 : -1);} + protected: int nvalues; // number of double values per entry - int ncount; // count - from all who are touching up to all in neigh list, depending on extraSurfDistance + int ncount; // count of eligible pair - all who are eligible for surfacesIntersect of surfacesClose + int ncount_added_via_pair; // count actually added via call from pair_gran // might be lower than ncount because is based on hasForceUpdate occurrences + // not all the surfacesClose calls have hasForceUpdate=true int newton_pair; @@ -100,10 +156,9 @@ class ComputePairGranLocal : public Compute { int ipair; - int posflag,velflag,idflag,fflag,fnflag,ftflag,tflag,hflag,aflag,dflag,hfflag; + int posflag,velflag,idflag,fflag,fnflag,ftflag,torqueflag,histflag,areaflag,deltaflag,heatflag; bool verbose; - double extraSurfDistance; int dnum; diff --git a/src/contact_models.cpp b/src/contact_models.cpp index 6c4cc13cba04742884410c490c1e4ad544e4322b..aff836af41f80c6e675942a751045bb86734a783 100644 --- a/src/contact_models.cpp +++ b/src/contact_models.cpp @@ -74,10 +74,10 @@ namespace ContactModels { int64_t generate_gran_hashcode(int model, int tangential, int cohesion, int rolling, int surface) { return (((int64_t)model)) | - (((int64_t)tangential) << 4) | - (((int64_t)cohesion) << 8) | - (((int64_t)rolling) << 12) | - (((int64_t)surface) << 16); + (((int64_t)tangential) << 6) | + (((int64_t)cohesion) << 12) | + (((int64_t)rolling) << 18) | + (((int64_t)surface) << 24); } Factory::Factory() { diff --git a/src/contact_models.h b/src/contact_models.h index 0d506b011124b99cebb1628b5b5b81bec510646c..7ec608aed431d25c69c48b693349424af0a75a48 100644 --- a/src/contact_models.h +++ b/src/contact_models.h @@ -92,10 +92,10 @@ namespace ContactModels static const int SURFACE = S; static const int64_t HASHCODE = (((int64_t)M)) | - (((int64_t)T) << 4) | - (((int64_t)C) << 8) | - (((int64_t)R) << 12) | - (((int64_t)S) << 16); + (((int64_t)T) << 6) | + (((int64_t)C) << 12) | + (((int64_t)R) << 18) | + (((int64_t)S) << 24); }; int64_t generate_gran_hashcode(int model, int tangential, int cohesion, int rolling, int surface); @@ -125,6 +125,7 @@ namespace ContactModels inline void beginPass(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces); inline void endPass(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces); inline void registerSettings(Settings & settings); + inline void postSettings(); inline void connectToProperties(PropertyRegistry & registry); inline void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces); inline void surfacesClose(SurfacesCloseData & scdata, ForceData & i_forces, ForceData & j_forces); @@ -239,6 +240,7 @@ namespace ContactModels inline void postSettings() { surfaceModel.postSettings(); + normalModel.postSettings(); } inline void connectToProperties(PropertyRegistry & registry) diff --git a/src/container_base.cpp b/src/container_base.cpp index 1b43ea77f35c75d5ae081a84eed7eec1d923fd8d..64b57b2339b3ab81e39937fb1d7335ff375042cf 100644 --- a/src/container_base.cpp +++ b/src/container_base.cpp @@ -42,12 +42,17 @@ ------------------------------------------------------------------------- */ #include "container_base.h" -#include <string.h> +#include "string_liggghts.h" +#include "stdio.h" +#include <string> #define GROW 100 using namespace LAMMPS_NS; + const char * ContainerBase::AVERAGESUFFIX = "_average"; + const char * ContainerBase::MEANSQUARESUFFIX = "_meansquare"; + /* ---------------------------------------------------------------------- constructor ------------------------------------------------------------------------- */ @@ -59,7 +64,13 @@ using namespace LAMMPS_NS; restartType_(RESTART_TYPE_UNDEFINED), scalePower_(-1), useDefault_(false), - container_statistics_raw_data_(0) + container_statistics_raw_data_(0), + container_statistics_scale_data_(0), + container_statistics_reduced_scale_data_(0), + statLevel_(0), + weighting_factor_(0.1), + scalingContainer_(false), + averaging_forget_(false) { } @@ -70,7 +81,13 @@ using namespace LAMMPS_NS; restartType_(RESTART_TYPE_UNDEFINED), scalePower_(-1), useDefault_(false), - container_statistics_raw_data_(0) + container_statistics_raw_data_(0), + container_statistics_scale_data_(0), + container_statistics_reduced_scale_data_(0), + statLevel_(0), + weighting_factor_(0.1), + scalingContainer_(false), + averaging_forget_(false) { if(_id) { @@ -86,7 +103,13 @@ using namespace LAMMPS_NS; restartType_(RESTART_TYPE_UNDEFINED), scalePower_(-1), useDefault_(false), - container_statistics_raw_data_(0) + container_statistics_raw_data_(0), + container_statistics_scale_data_(0), + container_statistics_reduced_scale_data_(0), + statLevel_(0), + weighting_factor_(0.1), + scalingContainer_(false), + averaging_forget_(false) { setProperties(_id, _comm, _ref,_restart,_scalePower); } @@ -98,7 +121,13 @@ using namespace LAMMPS_NS; restartType_(orig.restartType_), scalePower_(orig.scalePower_), useDefault_(orig.useDefault_), - container_statistics_raw_data_(orig.container_statistics_raw_data_) + container_statistics_raw_data_(orig.container_statistics_raw_data_), + container_statistics_scale_data_(orig.container_statistics_scale_data_), + container_statistics_reduced_scale_data_(orig.container_statistics_reduced_scale_data_), + statLevel_(orig.statLevel_), + weighting_factor_(orig.weighting_factor_), + scalingContainer_(orig.scalingContainer_), + averaging_forget_(orig.averaging_forget_) { } @@ -154,20 +183,39 @@ using namespace LAMMPS_NS; set container containing raw data for statistics calc ------------------------------------------------------------------------- */ - void ContainerBase::setContainerStatistics(class ContainerBase *_cb_stat) + void ContainerBase::setContainerStatistics(double _weighting_factor, class ContainerBase *_cb_stat, + class ContainerBase *_cb_scale, class ContainerBase *_cb_red_scale, bool _forget) { + weighting_factor_ = _weighting_factor; container_statistics_raw_data_ = _cb_stat; + container_statistics_scale_data_ = _cb_scale; + container_statistics_reduced_scale_data_ = _cb_red_scale; + averaging_forget_ = _forget; + + statLevel_ = container_statistics_raw_data_->getStatLevel()+1; } /* ---------------------------------------------------------------------- - calc statistics - can be ave or variance + calc statistics - can be average or mean square ------------------------------------------------------------------------- */ - bool ContainerBase::calcStatistics(double weighting_factor) + bool ContainerBase::calcStatistics() { - if(strstr(id_,"average")) - return calcAveFromContainer(weighting_factor); - if(strstr(id_,"variance")) - return calcVarFromContainer(weighting_factor); + if(strEndWith(id_,AVERAGESUFFIX)) + return calcAvgFromContainer(); + if(strEndWith(id_,MEANSQUARESUFFIX)) + return calcMeanSquareFromContainer(); return false; } + + bool ContainerBase::updateScalingContainer() + { + if(strEndWith(id_,AVERAGESUFFIX)) + return calcSumFromContainer(); + return false; + } + + bool ContainerBase::normalizeStatistics() + { + return normalizeContainer(); + } diff --git a/src/container_base.h b/src/container_base.h index bb10d5237b8c69f9afd0f9b2f94768db292ee0c0..9d48e7894ae3a8fcc3f8046ccbbaa194976011cc 100644 --- a/src/container_base.h +++ b/src/container_base.h @@ -68,7 +68,8 @@ namespace LAMMPS_NS void setProperties(const char *_id, const char* _comm, const char* _ref, const char *_restart,int _scalePower = 1); bool propertiesSetCorrectly(); - void setContainerStatistics(class ContainerBase *_cb_stat); + void setContainerStatistics(double _weighting_factor, class ContainerBase *_cb_stat, class ContainerBase *_cb_scale, + class ContainerBase *_cb_red_scale = 0, bool _forget = true); inline const char* id() {return id_; } @@ -82,6 +83,7 @@ namespace LAMMPS_NS virtual void addZero() = 0; virtual void addUninitialized(int n) = 0; virtual int size() const = 0; + virtual int capacity() const = 0; virtual int nVec() const = 0; virtual int lenVec() const = 0; virtual void* begin_slow_dirty() = 0; @@ -98,10 +100,14 @@ namespace LAMMPS_NS virtual bool setFromContainer(ContainerBase *cont) = 0; bool isStatisticsContainer() - { return (0!=container_statistics_raw_data_); } - bool calcStatistics(double weighting_factor); - virtual bool calcAveFromContainer(double weighting_factor) = 0; - virtual bool calcVarFromContainer(double weighting_factor) = 0; + { return (container_statistics_raw_data_!=0); } + bool calcStatistics(); + bool updateScalingContainer(); + bool normalizeStatistics(); + virtual bool calcAvgFromContainer() = 0; + virtual bool calcMeanSquareFromContainer() = 0; + virtual bool calcSumFromContainer() = 0; + virtual bool normalizeContainer() = 0; virtual void scale(double factor) = 0; virtual void move(double *dx) = 0; @@ -114,6 +120,21 @@ namespace LAMMPS_NS inline bool useDefault() { return useDefault_ ; } + inline int getStatLevel() const + { return statLevel_; } + + bool isScalingContainer() const + { return scalingContainer_; } + + void setScalingContainer(bool _value) + { scalingContainer_ = _value; } + + inline void setWeightingFactor(double _value) + { weighting_factor_ = _value; } + + inline void setAveragingForget(bool _value) + { averaging_forget_ = _value; } + // buffer functions for parallelization virtual int bufSize(int operation = OPERATION_UNDEFINED, @@ -141,6 +162,10 @@ namespace LAMMPS_NS virtual int popElemFromBuffer(double *buf,int operation, bool scale=false,bool translate=false, bool rotate=false) = 0; + // static elements + static const char * AVERAGESUFFIX; + static const char * MEANSQUARESUFFIX; + protected: ContainerBase(const char *_id, const char* _comm, const char* _ref, const char *_restart,int _scalePower); @@ -166,6 +191,16 @@ namespace LAMMPS_NS class ContainerBase *container_statistics_raw_data_; + class ContainerBase *container_statistics_scale_data_; + class ContainerBase *container_statistics_reduced_scale_data_; + + int statLevel_; + double weighting_factor_; + + bool scalingContainer_; + + bool averaging_forget_; + private: ContainerBase(); diff --git a/src/custom_value_tracker.cpp b/src/custom_value_tracker.cpp index c278b1d8af5d748377cd180466aea08025c8c57c..e44e413028752c08e4466b78a27852aaac377ae1 100644 --- a/src/custom_value_tracker.cpp +++ b/src/custom_value_tracker.cpp @@ -52,7 +52,7 @@ using namespace LAMMPS_NS; CustomValueTracker::CustomValueTracker(LAMMPS *lmp,AbstractMesh *_ownerMesh) : Pointers(lmp), ownerMesh_(_ownerMesh), - capacityElement_(0) + capacityElement_(GROW_CONTAINER()) { } @@ -67,15 +67,6 @@ using namespace LAMMPS_NS; { } - /* ---------------------------------------------------------------------- - memory management - ------------------------------------------------------------------------- */ - - int CustomValueTracker::getCapacity() - { - return capacityElement_; - } - /* ---------------------------------------------------------------------- check if all containers have same length ------------------------------------------------------------------------- */ @@ -137,12 +128,26 @@ using namespace LAMMPS_NS; } /* ---------------------------------------------------------------------- - calc statistics (averages, variances) + calc statistics (averages, mean square) ------------------------------------------------------------------------- */ - bool CustomValueTracker::calcStatistics(double weighting_factor) + bool CustomValueTracker::calcStatistics() + { + return elementProperties_.calcStatistics(); + } + + void CustomValueTracker::setWeightingFactor(double _weighting_factor) { - return elementProperties_.calcStatistics(weighting_factor); + for (int i=0; i < elementProperties_.size(); ++i) + { + ContainerBase* iElem = elementProperties_.getBasePointerByIndex(i); + if (iElem->getStatLevel() < 2) + iElem->setWeightingFactor(_weighting_factor); + else + //TODO: hard coded different weighting factor for higher statistics level + // compare with CustomValueTracker::addElementProperty + iElem->setWeightingFactor(5*_weighting_factor); + } } /* ---------------------------------------------------------------------- diff --git a/src/custom_value_tracker.h b/src/custom_value_tracker.h index 4edcf2ef0d2460c16a8534e294e91858cb35acc5..7d5facb281e4032d92ffb194a277ef8c9b7bf23d 100644 --- a/src/custom_value_tracker.h +++ b/src/custom_value_tracker.h @@ -65,7 +65,8 @@ namespace LAMMPS_NS template<typename T> T* addElementProperty(const char *_id, const char* _comm, const char* _ref, const char *_restart, - int _scalePower = 1, int _init_len = 0, const char *_statistics = 0); + int _scalePower = 1, int _init_len = 0, const char *_statistics = 0, + const double _weighting_factor = 1, const char *_id_scale = 0, const bool _forget = true); template<typename T> T* getElementProperty(const char *_id); @@ -106,6 +107,7 @@ namespace LAMMPS_NS inline void addUninitializedElement(); inline void addZeroElement(); inline void deleteAllElements(); + inline void deleteRestart(bool scale,bool translate,bool rotate); inline void deleteElement(int i); inline void deleteForwardElement(int i,bool scale,bool translate,bool rotate); inline void deleteRestartElement(int i,bool scale,bool translate,bool rotate); @@ -115,7 +117,21 @@ namespace LAMMPS_NS void storeOrig(); void resetToOrig(); - bool calcStatistics(double weighting_factor); + bool calcStatistics(); + + template<typename T> + T* getAvgElementProperty(const char *_id); + + template<typename T> + T* getMeanSquareElementProperty(const char *_id); + + template<typename T> + T* getAvgAvgElementProperty(const char *_id); + + template<typename T> + T* getAvgMeanSquareElementProperty(const char *_id); + + void setWeightingFactor(double _weighting_factor); inline void storeGlobalPropOrig(const char *_id); inline void resetGlobalPropToOrig(const char *_id); @@ -147,11 +163,6 @@ namespace LAMMPS_NS inline int pushGlobalPropsToBuffer(double *buf, int operation,bool scale,bool translate, bool rotate); inline int popGlobalPropsFromBuffer(double *buf, int operation,bool scale,bool translate, bool rotate); - // mem managenement - - int getCapacity(); - inline void grow(int to); - private: class AbstractMesh *ownerMesh_; diff --git a/src/custom_value_tracker_I.h b/src/custom_value_tracker_I.h index 1a2debb643a6dd034b12f5d14b0df9f5f58382f0..04cec6260cda4022f9b02e3b2f6566831b35d563 100644 --- a/src/custom_value_tracker_I.h +++ b/src/custom_value_tracker_I.h @@ -52,7 +52,8 @@ template<typename T> T* CustomValueTracker::addElementProperty(const char *_id, const char* _comm, const char* _ref, const char *_restart, - int _scalePower, int _init_len,const char *_statistics) + int _scalePower, int _init_len, const char *_statistics, + const double _weighting_factor, const char *_id_scale,const bool _forget ) { // error if property exists already if(elementProperties_.getPointerById<T>(_id)) @@ -67,7 +68,7 @@ std::string id_string(_id); // add property - elementProperties_.add<T>(_id,_comm,_ref,_restart,_scalePower); + ContainerBase * cb_new = elementProperties_.add<T>(_id,_comm,_ref,_restart,_scalePower); id_list.push_back(id_string); // check if properties were set correctly @@ -83,15 +84,35 @@ // add to statistics if applicable if(_statistics) { - if(strstr(_statistics,"average")) + if(strstr(_statistics,ContainerBase::AVERAGESUFFIX)) { - elementProperties_.add<T>(id_string.append("_average").c_str(),_comm,_ref,_restart,_scalePower)->setContainerStatistics(elementProperties_.getPointerById<T>(_id)); - id_list.push_back(id_string.append("_average")); + std::string id_string_ave = id_string; + id_string_ave.append(ContainerBase::AVERAGESUFFIX); + T* cb_average = elementProperties_.add<T>(id_string_ave.c_str(),_comm,_ref,_restart,_scalePower); + cb_average->setContainerStatistics(_weighting_factor, cb_new,0,0,_forget ); + id_list.push_back(id_string_ave); + + if(strstr(_statistics,"avgVar")) + { + // this one uses the average as reference field + // TODO: Hard-coded higher weighting factor for second stage statistics + std::string id_string_avg_avg = id_string_ave; + id_string_avg_avg.append(ContainerBase::AVERAGESUFFIX); + elementProperties_.add<T>(id_string_avg_avg.c_str(),_comm,_ref,_restart,_scalePower)->setContainerStatistics(5*_weighting_factor, cb_average,0,0,_forget ); + id_list.push_back(id_string_avg_avg); + + std::string id_string_avg_mean_square = id_string_ave; + id_string_avg_mean_square.append(ContainerBase::MEANSQUARESUFFIX); + elementProperties_.add<T>(id_string_avg_mean_square.c_str(),_comm,_ref,_restart,_scalePower)->setContainerStatistics(5*_weighting_factor, cb_average,0,0,_forget ); + id_list.push_back(id_string_avg_mean_square); + } } - if(strstr(_statistics,"variance")) + if(strstr(_statistics,ContainerBase::MEANSQUARESUFFIX)) { - elementProperties_.add<T>(id_string.append("_variance").c_str(),_comm,_ref,_restart,_scalePower)->setContainerStatistics(elementProperties_.getPointerById<T>(_id)); - id_list.push_back(id_string.append("_variance")); + std::string id_string_mean_square = id_string; + id_string_mean_square.append(ContainerBase::MEANSQUARESUFFIX); + elementProperties_.add<T>(id_string_mean_square.c_str(),_comm,_ref,_restart,_scalePower)->setContainerStatistics(_weighting_factor, cb_new,0,0,_forget ); + id_list.push_back(id_string_mean_square); } } @@ -147,16 +168,6 @@ return globalProperties_.getPointerById<T>(_id); } - /* ---------------------------------------------------------------------- - mem management - ------------------------------------------------------------------------- */ - - void CustomValueTracker::grow(int to) - { - elementProperties_.grow(to); - capacityElement_ = to; - } - /* ---------------------------------------------------------------------- get reference ------------------------------------------------------------------------- */ @@ -194,6 +205,38 @@ return globalProperties_.getPointerById<T>(_id); } + template<typename T> + T* CustomValueTracker::getAvgElementProperty(const char *_id) + { + std::string id_string(_id); + id_string.append(ContainerBase::AVERAGESUFFIX); + return getElementProperty<T>(id_string.c_str()); + } + + template<typename T> + T* CustomValueTracker::getMeanSquareElementProperty(const char *_id) + { + std::string id_string(_id); + id_string.append(ContainerBase::MEANSQUARESUFFIX); + return getElementProperty<T>(id_string.c_str()); + } + + template<typename T> + T* CustomValueTracker::getAvgAvgElementProperty(const char *_id) + { + std::string id_string(_id); + id_string.append(ContainerBase::AVERAGESUFFIX).append(ContainerBase::AVERAGESUFFIX); + return getElementProperty<T>(id_string.c_str()); + } + + template<typename T> + T* CustomValueTracker::getAvgMeanSquareElementProperty(const char *_id) + { + std::string id_string(_id); + id_string.append(ContainerBase::AVERAGESUFFIX).append(ContainerBase::MEANSQUARESUFFIX); + return getElementProperty<T>(id_string.c_str()); + } + /* ---------------------------------------------------------------------- set property ------------------------------------------------------------------------- */ @@ -273,6 +316,15 @@ elementProperties_.deleteAllElements(); } + /* ---------------------------------------------------------------------- + delete all elements + ------------------------------------------------------------------------- */ + + void CustomValueTracker::deleteRestart(bool scale,bool translate,bool rotate) + { + elementProperties_.deleteRestart(scale,translate,rotate); + } + /* ---------------------------------------------------------------------- delete element i ------------------------------------------------------------------------- */ diff --git a/src/domain_I.h b/src/domain_I.h index e38cab008b45a9c81ed296930e82445c78b57bd9..e08e8f40d3b53c02aa23e36891f7c8e33e48122b 100644 --- a/src/domain_I.h +++ b/src/domain_I.h @@ -169,27 +169,25 @@ inline void Domain::min_subbox_extent(double &min_extent,int &dim) } /* ---------------------------------------------------------------------- - domain check - not used very often, so not inlined + domain check ------------------------------------------------------------------------- */ inline int Domain::is_periodic_ghost(int i) { + if(i < atom->nlocal) return 0; + if(is_wedge) return is_periodic_ghost_wedge(i); int idim; - int nlocal = atom->nlocal; double *x = atom->x[i]; - double halfskin = 0.5*neighbor->skin; + const double cutneighmax = neighbor->cutneighmax; + + for(idim = 0; idim < 3; idim++) + if ((x[idim] < (boxlo[idim]+cutneighmax) || x[idim] > (boxhi[idim]-cutneighmax)) && periodicity[idim]) + + return 1; - if(i < nlocal) return 0; - else - { - for(idim = 0; idim < 3; idim++) - if ((x[idim] < (boxlo[idim]+halfskin) || x[idim] > (boxhi[idim]-halfskin)) && periodicity[idim]) - - return 1; - } return 0; } diff --git a/src/dump.h b/src/dump.h index eb72ce375ec8ce7c3c7f87ec04a44d4124dcd186..92544c39b3e1f9add152af1a256748aa77a67070 100644 --- a/src/dump.h +++ b/src/dump.h @@ -53,6 +53,9 @@ namespace LAMMPS_NS { class Dump : protected Pointers { + + friend class Info; + public: char *id; // user-defined name of Dump char *style; // style of Dump diff --git a/src/dump_atom_vtk.h b/src/dump_atom_vtk.h index 85d132e9154287f2401b03dafa885bf8640a9571..4bad7e39b3ec6e8c7d49738e0640a0c73ce7b686 100644 --- a/src/dump_atom_vtk.h +++ b/src/dump_atom_vtk.h @@ -35,7 +35,7 @@ Anton Gladky(TU Bergakademie Freiberg), gladky.anton@gmail.com ------------------------------------------------------------------------- */ -#if defined(LAMMPS_VTK) // NP do not use #ifdef here (VS C++ bug) +#if defined(LAMMPS_VTK) #ifdef DUMP_CLASS DumpStyle(atom/vtk,DumpATOMVTK) diff --git a/src/dump_local_gran_vtk.cpp b/src/dump_local_gran_vtk.cpp new file mode 100644 index 0000000000000000000000000000000000000000..725dacacc31c2800b76c7a7e7049e165c45c8fbe --- /dev/null +++ b/src/dump_local_gran_vtk.cpp @@ -0,0 +1,1029 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2014- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#ifdef LAMMPS_VTK + +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "dump_local_gran_vtk.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "region.h" +#include "group.h" +#include "input.h" +#include "variable.h" +#include "update.h" +#include "modify.h" +#include "compute.h" +#include "compute_pair_gran_local_bond.h" +#include "fix.h" +#include "memory.h" +#include "error.h" +#include <vector> +#include <sstream> +#include <vtkVersion.h> +#ifndef VTK_MAJOR_VERSION +#include <vtkConfigure.h> +#endif +#include <vtkPointData.h> +#include <vtkCellData.h> +#include <vtkLine.h> +#include <vtkDoubleArray.h> +#include <vtkIntArray.h> +#include <vtkStringArray.h> +#include <vtkPolyData.h> +#include <vtkPolyDataWriter.h> +#include <vtkXMLPolyDataWriter.h> +#include <vtkXMLPPolyDataWriter.h> +#include <vtkRectilinearGrid.h> +#include <vtkRectilinearGridWriter.h> +#include <vtkXMLRectilinearGridWriter.h> +#include <vtkHexahedron.h> +#include <vtkUnstructuredGrid.h> +#include <vtkUnstructuredGridWriter.h> +#include <vtkXMLUnstructuredGridWriter.h> +#include <vtkXMLPUnstructuredGridWriter.h> + +using namespace LAMMPS_NS; + +enum{INT,DOUBLE,STRING}; // same as in DumpCFG +enum{VTK,VTP,VTU,PVTP,PVTU}; // file formats +enum{X1,X2,V1,V2,ID1,ID2,F,FN,FT,TORQUE,AREA,DELTA,HEAT}; // dumps positions, force, normal and tangential forces, torque + +#define INVOKED_VECTOR 2 +#define INVOKED_ARRAY 4 +#define INVOKED_PERATOM 8 +#define INVOKED_LOCAL 16 + +/* ---------------------------------------------------------------------- */ + +DumpLocalGranVTK::DumpLocalGranVTK(LAMMPS *lmp, int narg, char **arg) : + Dump(lmp, narg, arg) +{ + //if (narg == 5) error->all(FLERR,"No dump custom/vtk arguments specified"); + + clearstep = 1; + + nevery = force->inumeric(FLERR,arg[3]); + + if(narg < 6) + error->all(FLERR,"dump local/gran/vtk requires 6 arguments"); + + Compute *comp = modify->find_compute_id(arg[5]); + if(!comp || !dynamic_cast<ComputePairGranLocal*>(comp)) + error->all(FLERR,"dump local/gran/vtk requires a valid ID of a compute pair/gran/local to be provided"); + + cpgl_ = static_cast<ComputePairGranLocalBond*>(comp); + + // error if compute does not write pos + if(cpgl_->offset_x1() < 0 || cpgl_->offset_x2() < 0) + error->all(FLERR,"dump local/gran/vtk requires a valid ID of a compute pair/gran/local that writes the positions"); + + // do stuff which needs the cpgl_ ptr + size_one = cpgl_->get_nvalues(); + + pack_choice.clear(); + vtype.clear(); + name.clear(); + + // fill data into containers + define_properties(); + + iregion = -1; + idregion = NULL; + + // computes, fixes, variables which the dump accesses + + myarrays.clear(); + n_calls_ = 0; + + if (filewriter) reset_vtk_data_containers(); + + // atom selection arrays + + maxlocal = 0; + + label = NULL; + + { + // parallel vtp/vtu requires proc number to be preceded by underscore '_' + multiname_ex = NULL; + char *ptr = strchr(filename,'%'); + if (ptr) { + multiname_ex = new char[strlen(filename) + 16]; + *ptr = '\0'; + sprintf(multiname_ex,"%s_%d%s",filename,me,ptr+1); + *ptr = '%'; + } + } + + vtk_file_format = VTK; + + char *suffix = filename + strlen(filename) - strlen(".vtp"); + if (suffix > filename && strcmp(suffix,".vtp") == 0) { + if (multiproc) vtk_file_format = PVTP; + else vtk_file_format = VTP; + } else if (suffix > filename && strcmp(suffix,".vtu") == 0) { + if (multiproc) vtk_file_format = PVTU; + else vtk_file_format = VTU; + } + + if (vtk_file_format == VTK) { // no multiproc support for legacy vtk format + if (me != 0) filewriter = 0; + fileproc = 0; + multiproc = 0; + nclusterprocs = nprocs; + } + + filecurrent = NULL; + parallelfilecurrent = NULL; +} + +/* ---------------------------------------------------------------------- */ + +DumpLocalGranVTK::~DumpLocalGranVTK() +{ + delete [] filecurrent; + delete [] parallelfilecurrent; + delete [] multiname_ex; + + delete [] idregion; + delete [] label; +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::init_style() +{ + + // setup function ptrs + + header_choice = &DumpLocalGranVTK::header_vtk; + + if (vtk_file_format == VTP || vtk_file_format == PVTP) + write_choice = &DumpLocalGranVTK::write_vtp; + else if (vtk_file_format == VTU || vtk_file_format == PVTU) + write_choice = &DumpLocalGranVTK::write_vtu; + else + write_choice = &DumpLocalGranVTK::write_vtk; + + // set index and check validity of region + + if (iregion >= 0) { + iregion = domain->find_region(idregion); + if (iregion == -1) + error->all(FLERR,"Region ID for dump custom/vtk does not exist"); + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write_header(bigint /*ndump*/) +{ +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::header_vtk(bigint) +{ +} + +/* ---------------------------------------------------------------------- */ + +int DumpLocalGranVTK::count() +{ + + int nmine; + n_calls_ = 0; + + //TODO generalize + //also check if have same length + cpgl_->compute_local(); + cpgl_->invoked_flag |= INVOKED_LOCAL; + + nchoose = cpgl_->get_ncount(); + + return nchoose; +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write() +{ + + // nme = # of dump lines this proc contributes to dump + + nme = count(); + + // ntotal = total # of dump lines in snapshot + // nmax = max # of dump lines on any proc + + bigint bnme = nme; + MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); + + int nmax; + if (multiproc != nprocs) MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world); + else nmax = nme; + + // write timestep header + // for multiproc, + // nheader = # of lines in this file via Allreduce on clustercomm + + bigint nheader = ntotal; + if (multiproc) + MPI_Allreduce(&bnme,&nheader,1,MPI_LMP_BIGINT,MPI_SUM,clustercomm); + + if (filewriter) write_header(nheader); + + // insure buf is sized for packing and communicating + // use nmax to insure filewriter proc can receive info from others + // limit nmax*size_one to int since used as arg in MPI calls + + if (nmax > maxbuf) { + if ((bigint) nmax * size_one > MAXSMALLINT) + error->all(FLERR,"Too much per-proc info for dump"); + maxbuf = nmax; + memory->destroy(buf); + memory->create(buf,maxbuf*size_one,"dump:buf"); + + } + + // insure ids buffer is sized for sorting + + if (sort_flag && sortcol == 0 && nmax > maxids) { + maxids = nmax; + memory->destroy(ids); + memory->create(ids,maxids,"dump:ids"); + } + + // pack my data into buf + // if sorting on IDs also request ID list from pack() + // sort buf as needed + + if (sort_flag && sortcol == 0) pack(ids); + else pack(NULL); + if (sort_flag) sort(); + + // filewriter = 1 = this proc writes to file + // ping each proc in my cluster, receive its data, write data to file + // else wait for ping from fileproc, send my data to fileproc + + int tmp,nlines; + MPI_Status status; + MPI_Request request; + + // comm and output buf of doubles + + if (filewriter) { + for (int iproc = 0; iproc < nclusterprocs; iproc++) { + if (iproc) { + MPI_Irecv(buf,maxbuf*size_one,MPI_DOUBLE,me+iproc,0,world,&request); + MPI_Send(&tmp,0,MPI_INT,me+iproc,0,world); + MPI_Wait(&request,&status); + MPI_Get_count(&status,MPI_DOUBLE,&nlines); + nlines /= size_one; + } else nlines = nme; + + write_data(nlines,buf); + } + } else { + MPI_Recv(&tmp,0,MPI_INT,fileproc,0,world,&status); + MPI_Rsend(buf,nme*size_one,MPI_DOUBLE,fileproc,0,world); + } + +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::pack(int *ids) +{ + int n = 0; + for (std::map<int,FnPtrPack>::iterator it = pack_choice.begin(); it != pack_choice.end(); ++it) + { + (this->*(it->second))(n); + + // increase n by length of data + if(vector_set.find(it->first) != vector_set.end()) + n += 3; + else + n++; + + } + + // similar to dump local, IDs are not used here (since are atom IDS +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write_data(int n, double *mybuf) +{ + (this->*write_choice)(n,mybuf); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::setFileCurrent() { + delete [] filecurrent; + filecurrent = NULL; + + char *filestar = filename; + if (multiproc) { + if (multiproc > 1) { // if dump_modify fileper or nfile was used + delete [] multiname_ex; + multiname_ex = NULL; + char *ptr = strchr(filename,'%'); + if (ptr) { + int id; + if (me + nclusterprocs == nprocs) // last filewriter + id = multiproc -1; + else + id = me/nclusterprocs; + multiname_ex = new char[strlen(filename) + 16]; + *ptr = '\0'; + sprintf(multiname_ex,"%s_%d%s",filename,id,ptr+1); + *ptr = '%'; + } + } // else multiname_ex built in constructor is OK + filestar = multiname_ex; + } + + if (multifile == 0) { + filecurrent = new char[strlen(filestar) + 1]; + strcpy(filecurrent, filestar); + } else { + filecurrent = new char[strlen(filestar) + 16]; + char *ptr = strchr(filestar,'*'); + *ptr = '\0'; + if (padflag == 0) { + sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", + filestar,update->ntimestep,ptr+1); + } else { + char bif[8],pad[16]; + strcpy(bif,BIGINT_FORMAT); + sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]); + sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1); + } + *ptr = '*'; + } + + // filename of parallel file + if (multiproc && me == 0) { + delete [] parallelfilecurrent; + parallelfilecurrent = NULL; + + // remove '%' character and add 'p' to file extension + // -> string length stays the same + char *ptr = strchr(filename,'%'); + filestar = new char[strlen(filename) + 1]; + *ptr = '\0'; + sprintf(filestar,"%s%s",filename,ptr+1); + *ptr = '%'; + ptr = strrchr(filestar,'.'); + ptr++; + *ptr++='p'; + *ptr++='v'; + *ptr++='t'; + *ptr++= (vtk_file_format == PVTP)?'p':'u'; + *ptr++= 0; + + if (multifile == 0) { + parallelfilecurrent = new char[strlen(filestar) + 1]; + strcpy(parallelfilecurrent, filestar); + } else { + parallelfilecurrent = new char[strlen(filestar) + 16]; + char *ptr = strchr(filestar,'*'); + *ptr = '\0'; + if (padflag == 0) { + sprintf(parallelfilecurrent,"%s" BIGINT_FORMAT "%s", + filestar,update->ntimestep,ptr+1); + } else { + char bif[8],pad[16]; + strcpy(bif,BIGINT_FORMAT); + sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]); + sprintf(parallelfilecurrent,pad,filestar,update->ntimestep,ptr+1); + } + *ptr = '*'; + } + delete [] filestar; + filestar = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::buf2arrays(int n, double *mybuf) +{ + + for (int idata=0; idata < n; ++idata) { + + // stores the ID of newly added points + vtkIdType pid[2]; + + pid[0] = points->InsertNextPoint(mybuf[idata*size_one],mybuf[idata*size_one+1],mybuf[idata*size_one+2]); + pid[1] = points->InsertNextPoint(mybuf[idata*size_one+3],mybuf[idata*size_one+4],mybuf[idata*size_one+5]); + + // define the line going from point pid[0] to pid[1] + vtkSmartPointer<vtkLine> line0 = vtkSmartPointer<vtkLine>::New(); + line0->GetPointIds()->SetId(0,pid[0]); + line0->GetPointIds()->SetId(1,pid[1]); + + lineCells->InsertNextCell(line0); + + int j = 6; // 0,1,2,3,4,5 = 2 * (x,y,z) handled just above + for (std::map<int, vtkSmartPointer<vtkAbstractArray> >::iterator it=myarrays.begin(); it!=myarrays.end(); ++it) { + + vtkAbstractArray *paa = it->second; + if (it->second->GetNumberOfComponents() == 3) { + switch (vtype[it->first]) { + case INT: + { + int iv3[3] = { static_cast<int>(mybuf[idata*size_one+j ]), + static_cast<int>(mybuf[idata*size_one+j+1]), + static_cast<int>(mybuf[idata*size_one+j+2]) }; + vtkIntArray *pia = static_cast<vtkIntArray*>(paa); + pia->InsertNextTupleValue(iv3); + break; + } + case DOUBLE: + { + vtkDoubleArray *pda = static_cast<vtkDoubleArray*>(paa); + pda->InsertNextTupleValue(&mybuf[idata*size_one+j]); + break; + } + } + j+=3; + } else { + switch (vtype[it->first]) { + case INT: + { + vtkIntArray *pia = static_cast<vtkIntArray*>(paa); + pia->InsertNextValue(mybuf[idata*size_one+j]); + break; + } + case DOUBLE: + { + vtkDoubleArray *pda = static_cast<vtkDoubleArray*>(paa); + pda->InsertNextValue(mybuf[idata*size_one+j]); + break; + } + } + ++j; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write_vtk(int n, double *mybuf) +{ + ++n_calls_; + + buf2arrays(n, mybuf); + + if (n_calls_ < nclusterprocs) + return; // multiple processors but only proc 0 is a filewriter (-> nclusterprocs procs contribute to the filewriter's output data) + + setFileCurrent(); + + { +#ifdef UNSTRUCTURED_GRID_VTK + + vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New(); + unstructuredGrid->SetPoints(points); + unstructuredGrid->SetCells(VTK_LINE, lineCells); + + for (std::map<int, vtkSmartPointer<vtkAbstractArray> >::iterator it=myarrays.begin(); it!=myarrays.end(); ++it) { + unstructuredGrid->GetCellData()->AddArray(it->second); + } + + vtkSmartPointer<vtkUnstructuredGridWriter> writer = vtkSmartPointer<vtkUnstructuredGridWriter>::New(); + +#else + vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); + polyData->SetPoints(points); + polyData->SetLines(lineCells); + + for (std::map<int, vtkSmartPointer<vtkAbstractArray> >::iterator it=myarrays.begin(); it!=myarrays.end(); ++it) { + polyData->GetCellData()->AddArray(it->second); + } + + vtkSmartPointer<vtkPolyDataWriter> writer = vtkSmartPointer<vtkPolyDataWriter>::New(); +#endif + + if(label) writer->SetHeader(label); + else writer->SetHeader("Generated by LIGGGHTS"); + + if (binary) writer->SetFileTypeToBinary(); + else writer->SetFileTypeToASCII(); + +#ifdef UNSTRUCTURED_GRID_VTK + #if VTK_MAJOR_VERSION < 6 + writer->SetInput(unstructuredGrid); + #else + writer->SetInputData(unstructuredGrid); + #endif +#else + #if VTK_MAJOR_VERSION < 6 + writer->SetInput(polyData); + #else + writer->SetInputData(polyData); + #endif +#endif + writer->SetFileName(filecurrent); + writer->Write(); + } + + reset_vtk_data_containers(); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write_vtp(int n, double *mybuf) +{ + ++n_calls_; + + buf2arrays(n, mybuf); + + if (n_calls_ < nclusterprocs) + return; // multiple processors but not all are filewriters (-> nclusterprocs procs contribute to the filewriter's output data) + + setFileCurrent(); + + { + vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); + + polyData->SetPoints(points); + polyData->SetLines(lineCells); + + for (std::map<int, vtkSmartPointer<vtkAbstractArray> >::iterator it=myarrays.begin(); it!=myarrays.end(); ++it) { + polyData->GetCellData()->AddArray(it->second); + } + + vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkSmartPointer<vtkXMLPolyDataWriter>::New(); + if (binary) writer->SetDataModeToBinary(); + else writer->SetDataModeToAscii(); + +#if VTK_MAJOR_VERSION < 6 + writer->SetInput(polyData); +#else + writer->SetInputData(polyData); +#endif + writer->SetFileName(filecurrent); + writer->Write(); + + if (me == 0) { + if (multiproc) { + vtkSmartPointer<vtkXMLPPolyDataWriter> pwriter = vtkSmartPointer<vtkXMLPPolyDataWriter>::New(); + pwriter->SetFileName(parallelfilecurrent); + pwriter->SetNumberOfPieces((multiproc > 1)?multiproc:nprocs); + if (binary) pwriter->SetDataModeToBinary(); + else pwriter->SetDataModeToAscii(); + +#if VTK_MAJOR_VERSION < 6 + pwriter->SetInput(polyData); +#else + pwriter->SetInputData(polyData); +#endif + pwriter->Write(); + } + } + } + + reset_vtk_data_containers(); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::write_vtu(int n, double *mybuf) +{ + ++n_calls_; + + buf2arrays(n, mybuf); + + if (n_calls_ < nclusterprocs) + return; // multiple processors but not all are filewriters (-> nclusterprocs procs contribute to the filewriter's output data) + + setFileCurrent(); + + { + vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New(); + + unstructuredGrid->SetPoints(points); + unstructuredGrid->SetCells(VTK_LINE, lineCells); + + for (std::map<int, vtkSmartPointer<vtkAbstractArray> >::iterator it=myarrays.begin(); it!=myarrays.end(); ++it) { + unstructuredGrid->GetCellData()->AddArray(it->second); + } + + vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New(); + if (binary) writer->SetDataModeToBinary(); + else writer->SetDataModeToAscii(); + +#if VTK_MAJOR_VERSION < 6 + writer->SetInput(unstructuredGrid); +#else + writer->SetInputData(unstructuredGrid); +#endif + writer->SetFileName(filecurrent); + writer->Write(); + + if (me == 0) { + if (multiproc) { + vtkSmartPointer<vtkXMLPUnstructuredGridWriter> pwriter = vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New(); + pwriter->SetFileName(parallelfilecurrent); + pwriter->SetNumberOfPieces((multiproc > 1)?multiproc:nprocs); + if (binary) pwriter->SetDataModeToBinary(); + else pwriter->SetDataModeToAscii(); + +#if VTK_MAJOR_VERSION < 6 + pwriter->SetInput(unstructuredGrid); +#else + pwriter->SetInputData(unstructuredGrid); +#endif + pwriter->Write(); + } + } + } + + reset_vtk_data_containers(); +} + +/* ---------------------------------------------------------------------- */ + +void DumpLocalGranVTK::reset_vtk_data_containers() +{ + points = vtkSmartPointer<vtkPoints>::New(); + lineCells = vtkSmartPointer<vtkCellArray>::New(); + + std::map<int,int>::iterator it=vtype.begin(); + + ++it; + ++it; + + for (; it!=vtype.end(); ++it) { + + // part 1: add VTK array to myarrays + switch(vtype[it->first]) { + case INT: + myarrays[it->first] = vtkSmartPointer<vtkIntArray>::New(); + break; + case DOUBLE: + myarrays[it->first] = vtkSmartPointer<vtkDoubleArray>::New(); + break; + case STRING: + myarrays[it->first] = vtkSmartPointer<vtkStringArray>::New(); + break; + } + + // part 2: if vector, set length to 3; set name + if (vector_set.find(it->first) != vector_set.end()) { + myarrays[it->first]->SetNumberOfComponents(3); + myarrays[it->first]->SetName(name[it->first].c_str()); + } else { + myarrays[it->first]->SetName(name[it->first].c_str()); + } + } +} + +/* ---------------------------------------------------------------------- */ + +// customize here + +void DumpLocalGranVTK::define_properties() +{ + pack_choice[X1] = &DumpLocalGranVTK::pack_x1; + vtype[X1] = DOUBLE; + name[X1] = "pos1"; + vector_set.insert(X1); + + pack_choice[X2] = &DumpLocalGranVTK::pack_x2; + vtype[X2] = DOUBLE; + name[X2] = "pos2"; + vector_set.insert(X2); + + if(cpgl_->offset_v1() > 0) + { + pack_choice[V1] = &DumpLocalGranVTK::pack_v1; + vtype[V1] = DOUBLE; + name[V1] = "vel1"; + vector_set.insert(V1); + } + + if(cpgl_->offset_v2() > 0) + { + pack_choice[V2] = &DumpLocalGranVTK::pack_v2; + vtype[V2] = DOUBLE; + name[V2] = "vel2"; + vector_set.insert(V2); + } + + if(cpgl_->offset_id1() > 0) + { + pack_choice[ID1] = &DumpLocalGranVTK::pack_id1; + vtype[ID1] = DOUBLE; + name[ID1] = "id1"; + //scalar + } + + if(cpgl_->offset_id2() > 0) + { + pack_choice[ID2] = &DumpLocalGranVTK::pack_id2; + vtype[ID2] = DOUBLE; + name[ID2] = "id2"; + //scalar + } + + if(cpgl_->offset_f() > 0) + { + pack_choice[F] = &DumpLocalGranVTK::pack_f; + vtype[F] = DOUBLE; + name[F] = "force"; + vector_set.insert(F); + } + + if(cpgl_->offset_fn() > 0) + { + pack_choice[FN] = &DumpLocalGranVTK::pack_fn; + vtype[FN] = DOUBLE; + name[FN] = "force_normal"; + vector_set.insert(FN); + } + + if(cpgl_->offset_ft() > 0) + { + pack_choice[FT] = &DumpLocalGranVTK::pack_ft; + vtype[FT] = DOUBLE; + name[FT] = "force_tangential"; + vector_set.insert(FT); + } + + if(cpgl_->offset_torque() > 0) + { + pack_choice[TORQUE] = &DumpLocalGranVTK::pack_torque; + vtype[TORQUE] = DOUBLE; + name[TORQUE] = "torque"; + vector_set.insert(TORQUE); + } + + if(cpgl_->offset_area() > 0) + { + + pack_choice[AREA] = &DumpLocalGranVTK::pack_area; + vtype[AREA] = DOUBLE; + name[AREA] = "contact_area"; + //scalar + } + + if(cpgl_->offset_delta() > 0) + { + pack_choice[DELTA] = &DumpLocalGranVTK::pack_delta; + vtype[DELTA] = DOUBLE; + name[DELTA] = "delta"; + //scalar + } + + if(cpgl_->offset_heat() > 0) + { + pack_choice[HEAT] = &DumpLocalGranVTK::pack_heat; + vtype[HEAT] = DOUBLE; + name[HEAT] = "heat_flux"; + //scalar + } +} + +/* ---------------------------------------------------------------------- */ + +int DumpLocalGranVTK::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0],"region") == 0) { + if (narg < 2) error->all(FLERR,"Illegal dump_modify command"); + if (strcmp(arg[1],"none") == 0) iregion = -1; + else { + iregion = domain->find_region(arg[1]); + if (iregion == -1) + error->all(FLERR,"Dump_modify region ID does not exist"); + delete [] idregion; + int n = strlen(arg[1]) + 1; + idregion = new char[n]; + strcpy(idregion,arg[1]); + } + return 2; + } + + if (strcmp(arg[0],"label") == 0) { + if (narg < 2) error->all(FLERR,"Illegal dump_modify command [label]"); + delete [] label; + int n = strlen(arg[1]) + 1; + label = new char[n]; + strcpy(label,arg[1]); + return 2; + } + + if (strcmp(arg[0],"binary") == 0) { + if (narg < 2) error->all(FLERR,"Illegal dump_modify command [binary]"); + if (strcmp(arg[1],"yes") == 0) binary = 1; + else if (strcmp(arg[1],"no") == 0) binary = 0; + else error->all(FLERR,"Illegal dump_modify command [binary]"); + return 2; + } + + if (strcmp(arg[0],"element") == 0) { + error->all(FLERR,"Dump local/bond/gran does not support dump_modify 'element' "); + return 0; + } + + if (strcmp(arg[0],"thresh") == 0) { + error->all(FLERR,"Dump local/bond/gran does not support dump_modify 'thresh' "); + } + + return 0; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory in buf, choose, variable arrays +------------------------------------------------------------------------- */ + +bigint DumpLocalGranVTK::memory_usage() +{ + bigint bytes = Dump::memory_usage(); + return bytes; +} + +/* ---------------------------------------------------------------------- + pack properties + TODO generalize function, and length of packing +------------------------------------------------------------------------- */ + +// customize here + +void DumpLocalGranVTK::pack_x1(int n) +{ + int offset = cpgl_->offset_x1(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_x2(int n) +{ + int offset = cpgl_->offset_x2(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_v1(int n) +{ + int offset = cpgl_->offset_v1(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_v2(int n) +{ + int offset = cpgl_->offset_v2(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_id1(int n) +{ + int offset = cpgl_->offset_id1(); + + for (int i = 0; i < nchoose; i++) { + buf[n] = cpgl_->get_data()[i][offset]; + n += size_one; + } +} + +void DumpLocalGranVTK::pack_id2(int n) +{ + int offset = cpgl_->offset_id2(); + + for (int i = 0; i < nchoose; i++) { + buf[n] = cpgl_->get_data()[i][offset]; + n += size_one; + } +} + +void DumpLocalGranVTK::pack_f(int n) +{ + int offset = cpgl_->offset_f(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_fn(int n) +{ + int offset = cpgl_->offset_fn(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_ft(int n) +{ + int offset = cpgl_->offset_ft(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_torque(int n) +{ + int offset = cpgl_->offset_torque(); + + for (int i = 0; i < nchoose; i++) { + vectorCopy3D(&cpgl_->get_data()[i][offset],&buf[n]); + n += size_one; + } +} + +void DumpLocalGranVTK::pack_area(int n) +{ + int offset = cpgl_->offset_area(); + + for (int i = 0; i < nchoose; i++) { + buf[n] = cpgl_->get_data()[i][offset]; + n += size_one; + } +} + +void DumpLocalGranVTK::pack_delta(int n) +{ + int offset = cpgl_->offset_delta(); + + for (int i = 0; i < nchoose; i++) { + buf[n] = cpgl_->get_data()[i][offset]; + n += size_one; + } +} + +void DumpLocalGranVTK::pack_heat(int n) +{ + int offset = cpgl_->offset_heat(); + + for (int i = 0; i < nchoose; i++) { + buf[n] = cpgl_->get_data()[i][offset]; + n += size_one; + } +} + +#endif diff --git a/src/dump_local_gran_vtk.h b/src/dump_local_gran_vtk.h new file mode 100644 index 0000000000000000000000000000000000000000..739e6df9db4766a2aa9ed645b20dec4f862defa0 --- /dev/null +++ b/src/dump_local_gran_vtk.h @@ -0,0 +1,172 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2014- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#if defined(LAMMPS_VTK) +#ifdef DUMP_CLASS + +DumpStyle(local/gran/vtk,DumpLocalGranVTK) + +#else + +#ifndef LMP_DUMP_LOCAL_GRAN_VTK_H +#define LMP_DUMP_LOCAL_GRAN_VTK_H + +#include "dump.h" +#include <map> +#include <set> +#include <string> + +#include <vtkSmartPointer.h> +#include <vtkPoints.h> +#include <vtkCellArray.h> + +class vtkAbstractArray; +class vtkRectilinearGrid; +class vtkUnstructuredGrid; + +namespace LAMMPS_NS { + +/** + * @brief DumpLocalGranVTK class + * write gran bond data to vtk files. + * + * Similar to the DumpCustomVTK class but uses the vtk library to write data to vtk simple + * legacy or xml format depending on the filename extension specified. (Since this + * conflicts with the way binary output is specified, dump_modify allows to set the + * binary flag for this dump command explicitly). + * In contrast to DumpCustom class the attributes to be packed are stored in a std::map + * to avoid duplicate entries and enforce correct ordering of vector components (except + * for computes and fixes - these have to be given in the right order in the input script). + * (Note: std::map elements are sorted by their keys.) + * This dump command does not support compressed files, buffering or custom format strings, + * multiproc is only supported by the xml formats, multifile option has to be used. + */ +class DumpLocalGranVTK : public Dump { + public: + DumpLocalGranVTK(class LAMMPS *, int, char **); + virtual ~DumpLocalGranVTK(); + + virtual void write(); + + protected: + + int nevery; // dump frequency for output + char *label; // string for dump file header + int iregion; // -1 if no region, else which region + char *idregion; // region ID + + int vtk_file_format; // which vtk file format to write (vtk, vtp, vtu ...) + + int nchoose; // # of selected local datums + int maxlocal; // size of atom selection and variable arrays + + // private methods + + class ComputePairGranLocal *cpgl_; + + virtual void init_style(); + virtual void write_header(bigint); + int count(); + void pack(int *); + virtual void write_data(int, double *); + bigint memory_usage(); + + int parse_fields(int, char **); + int add_compute(char *); + int add_fix(char *); + int add_variable(char *); + virtual int modify_param(int, char **); + + typedef void (DumpLocalGranVTK::*FnPtrHeader)(bigint); + FnPtrHeader header_choice; // ptr to write header functions + void header_vtk(bigint); + + typedef void (DumpLocalGranVTK::*FnPtrWrite)(int, double *); + FnPtrWrite write_choice; // ptr to write data functions + void write_vtk(int, double *); + void write_vtp(int, double *); + void write_vtu(int, double *); + + void define_properties(); + typedef void (DumpLocalGranVTK::*FnPtrPack)(int); + + std::map<int, FnPtrPack> pack_choice; // ptrs to pack functions + std::map<int, int> vtype; // data type for each attribute + std::map<int, std::string> name; // label for each attribute + std::set<int> vector_set; // set of vector attributes; defines which are vectors + + // vtk data containers + vtkSmartPointer<vtkPoints> points; // list of points, 2 points for each line cell + vtkSmartPointer<vtkCellArray> lineCells; // list of line cells + std::map<int, vtkSmartPointer<vtkAbstractArray> > myarrays; // list of a list of arrays that is presents data for each atom (x, v,...) + // is then added to the point cells upon writing + int n_calls_; + + char *filecurrent; + char *parallelfilecurrent; + char *multiname_ex; + + void setFileCurrent(); + void buf2arrays(int, double *); // transfer data from buf array to vtk arrays + void reset_vtk_data_containers(); + + // customize by adding a method prototype + void pack_x1(int); + void pack_x2(int); + void pack_v1(int); + void pack_v2(int); + void pack_id1(int); + void pack_id2(int); + void pack_id3(int); + void pack_f(int); + void pack_fn(int); + void pack_ft(int); + void pack_torque(int); + void pack_area(int); + void pack_delta(int); + void pack_heat(int); +}; + +} + +#endif +#endif +#endif + diff --git a/src/dump_mesh_vtk.cpp b/src/dump_mesh_vtk.cpp index e48ca79c3319e69c89247be4f82c5edaed36dd31..08ca887e3f537ebf1d94c5929662903d4ef4bd59 100644 --- a/src/dump_mesh_vtk.cpp +++ b/src/dump_mesh_vtk.cpp @@ -106,7 +106,9 @@ DumpMeshVTK::DumpMeshVTK(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, ar vector_container_names_(0), n_vector_containers_(0), container_args_(0), - n_container_bases_(0) + n_container_bases_(0), + points_neightri_len_max_(0), + points_neightri_(0) { if (narg < 5) error->all(FLERR,"Illegal dump mesh/vtk command"); @@ -319,6 +321,14 @@ DumpMeshVTK::~DumpMeshVTK() delete [] vector_containers_; delete [] scalar_container_names_; delete [] vector_container_names_; + + if(points_neightri_) + { + for (int i=0; i < points_neightri_len_max_; i++) + delete points_neightri_[i]; + + delete [] points_neightri_; + } } /* ---------------------------------------------------------------------- */ @@ -434,8 +444,8 @@ void DumpMeshVTK::getRefs() { sigma_n_[i] = meshList_[i]->prop().getElementProperty<ScalarContainer<double> >("sigma_n"); sigma_t_[i] = meshList_[i]->prop().getElementProperty<ScalarContainer<double> >("sigma_t"); - if(0 == comm->me && (!sigma_n_[i] || !sigma_t_[i])) - error->warning(FLERR,"Trying to dump stress for mesh which does not calculate stress, will dump '0' instead"); + //if(0 == comm->me && (!sigma_n_[i] || !sigma_t_[i])) + // error->warning(FLERR,"Trying to dump stress for mesh which does not calculate stress, will dump '0' instead"); } } if(dump_what_ & DUMP_STRESSCOMPONENTS) @@ -458,8 +468,8 @@ void DumpMeshVTK::getRefs() for(int i = 0; i < nMesh_; i++) { wear_[i] = meshList_[i]->prop().getElementProperty<ScalarContainer<double> >("wear"); - if(0 == comm->me && !wear_[i]) - error->warning(FLERR,"Trying to dump wear for mesh which does not calculate wear, will dump '0' instead"); + //if(0 == comm->me && !wear_[i]) + // error->warning(FLERR,"Trying to dump wear for mesh which does not calculate wear, will dump '0' instead"); } } if(dump_what_ & DUMP_TEMP) @@ -467,8 +477,8 @@ void DumpMeshVTK::getRefs() for(int i = 0; i < nMesh_; i++) { T_[i] = meshList_[i]->prop().getGlobalProperty<ScalarContainer<double> >("Temp"); - if(0 == comm->me && !T_[i]) - error->warning(FLERR,"Trying to dump temperature for mesh which does not calculate temperature, will dump '0' instead"); + //if(0 == comm->me && !T_[i]) + // error->warning(FLERR,"Trying to dump temperature for mesh which does not calculate temperature, will dump '0' instead"); } } if(dump_what_ & DUMP_MIN_ACTIVE_EDGE_DIST) @@ -720,7 +730,7 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) ScalarContainer<int> tri_points("DumpMeshVTK::tri_points"); bool add; for (int i = 0; i < n; i++) - { + { for (int j=0;j<3;j++) { add = true; @@ -748,20 +758,39 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) buf_pos += 9; - // points_neightri - class ScalarContainer<int> **points_neightri; - points_neightri = new ScalarContainer<int>*[(int)points.size()/3]; - for (int i=0; i < points.size()/3; i++) - points_neightri[i] = new ScalarContainer<int>("DumpMeshVTK::points_neightri"); + // points_neightri_ + + if(points.size()/3 > points_neightri_len_max_) + { + if(points_neightri_) + { + for (int i=0; i < points.size()/3; i++) + delete points_neightri_[i]; + + delete [] points_neightri_; + } + + points_neightri_ = new ScalarContainer<int>*[(int)points.size()/3]; + for (int i=0; i < points.size()/3; i++) + points_neightri_[i] = new ScalarContainer<int>("DumpMeshVTK::points_neightri"); + + points_neightri_len_max_ = points.size()/3; + } + else + { + for(int i = 0; i < points_neightri_len_max_; i++) + points_neightri_[i]->clearContainer(); + } + for (int i=0; i < 3*n; i+=3) { for (int j=0; j<3;j++) - points_neightri[tri_points.get(i+j)]->add(i/3); + points_neightri_[tri_points.get(i+j)]->add(i/3); } // write point data fprintf(fp,"DATASET UNSTRUCTURED_GRID\nPOINTS %d float\n", points.size()/3); - for (int i=0; i < points.size(); i+=3) + for (int i=0; i < points.size(); i+=3) fprintf(fp,"%f %f %f\n",points.get(i+0),points.get(i+1),points.get(i+2)); // write polygon data @@ -780,25 +809,25 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) if(dump_what_ & DUMP_STRESS) { // write pressure and shear stress - fprintf(fp,"SCALARS pressure float 1\nLOOKUP_TABLE default\n"); + fprintf(fp,"SCALARS normal_stress_average float 1\nLOOKUP_TABLE default\n"); m = buf_pos; for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; // write shear stress - fprintf(fp,"SCALARS shearstress float 1\nLOOKUP_TABLE default\n"); + fprintf(fp,"SCALARS shear_stress_average float 1\nLOOKUP_TABLE default\n"); m = buf_pos; for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -811,15 +840,15 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper1=0, helper2=0, helper3=0; - for (int j=0; j < points_neightri[i]->size();j++) + for (int j=0; j < points_neightri_[i]->size();j++) { - helper1 += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper2 += mybuf[m+1 + points_neightri[i]->get(j)*size_one]; - helper3 += mybuf[m+2 + points_neightri[i]->get(j)*size_one]; + helper1 += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper2 += mybuf[m+1 + points_neightri_[i]->get(j)*size_one]; + helper3 += mybuf[m+2 + points_neightri_[i]->get(j)*size_one]; } - helper1 /= points_neightri[i]->size(); - helper2 /= points_neightri[i]->size(); - helper3 /= points_neightri[i]->size(); + helper1 /= points_neightri_[i]->size(); + helper2 /= points_neightri_[i]->size(); + helper3 /= points_neightri_[i]->size(); fprintf(fp,"%f %f %f\n",helper1,helper2,helper3); } buf_pos += 3; @@ -833,8 +862,8 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -848,15 +877,15 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper1=0, helper2=0, helper3=0; - for (int j=0; j < points_neightri[i]->size();j++) + for (int j=0; j < points_neightri_[i]->size();j++) { - helper1 += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper2 += mybuf[m+1 + points_neightri[i]->get(j)*size_one]; - helper3 += mybuf[m+2 + points_neightri[i]->get(j)*size_one]; + helper1 += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper2 += mybuf[m+1 + points_neightri_[i]->get(j)*size_one]; + helper3 += mybuf[m+2 + points_neightri_[i]->get(j)*size_one]; } - helper1 /= points_neightri[i]->size(); - helper2 /= points_neightri[i]->size(); - helper3 /= points_neightri[i]->size(); + helper1 /= points_neightri_[i]->size(); + helper2 /= points_neightri_[i]->size(); + helper3 /= points_neightri_[i]->size(); fprintf(fp,"%f %f %f\n",helper1,helper2,helper3); } buf_pos += 3; @@ -870,8 +899,8 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -885,8 +914,8 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -900,8 +929,8 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -915,8 +944,8 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) for (int i = 0; i < points.size()/3; i++) { double helper=0; - for (int j=0; j < points_neightri[i]->size();j++) helper += mybuf[m + points_neightri[i]->get(j)*size_one]; - helper /= points_neightri[i]->size(); + for (int j=0; j < points_neightri_[i]->size();j++) helper += mybuf[m + points_neightri_[i]->get(j)*size_one]; + helper /= points_neightri_[i]->size(); fprintf(fp,"%f\n",helper); } buf_pos++; @@ -948,6 +977,7 @@ void DumpMeshVTK::write_data_ascii_point(int n, double *mybuf) { buf_pos++; } + return; } @@ -994,7 +1024,7 @@ void DumpMeshVTK::write_data_ascii_face(int n, double *mybuf) if(dump_what_ & DUMP_STRESS) { // write pressure and shear stress - fprintf(fp,"SCALARS pressure float 1\nLOOKUP_TABLE default\n"); + fprintf(fp,"SCALARS normal_stress_average float 1\nLOOKUP_TABLE default\n"); m = buf_pos; for (int i = 0; i < n; i++) { @@ -1004,7 +1034,7 @@ void DumpMeshVTK::write_data_ascii_face(int n, double *mybuf) buf_pos++; // write shear stress - fprintf(fp,"SCALARS shearstress float 1\nLOOKUP_TABLE default\n"); + fprintf(fp,"SCALARS shear_stress_average float 1\nLOOKUP_TABLE default\n"); m = buf_pos; for (int i = 0; i < n; i++) { diff --git a/src/dump_mesh_vtk.h b/src/dump_mesh_vtk.h index c947d6bc6cffe20ff18438860319c5472d8af676..6198916d95efd3b43096d450ddfd167df887d911 100644 --- a/src/dump_mesh_vtk.h +++ b/src/dump_mesh_vtk.h @@ -104,6 +104,9 @@ class DumpMeshVTK : public Dump { char **container_args_; int n_container_bases_; + int points_neightri_len_max_; + class ScalarContainer<int> **points_neightri_; + int modify_param(int, char **); void write_header(bigint ndump); int count(); diff --git a/src/fix_base_liggghts.cpp b/src/fix_base_liggghts.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c72ff578fa6ce3ae7128826754e6568ab6dfc03e --- /dev/null +++ b/src/fix_base_liggghts.cpp @@ -0,0 +1,218 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2015- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#include "math.h" +#include "string.h" +#include "stdlib.h" +#include "fix_base_liggghts.h" +#include "atom.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "update.h" +#include "respa.h" +#include "region.h" +#include "domain.h" +#include "modify.h" +#include "atom_vec.h" +#include "comm.h" +#include "fix_multisphere.h" +#include "multisphere_parallel.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixBaseLiggghts::FixBaseLiggghts(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), + support_respa_(false), + nlevels_respa_(0), + do_need_radius_(true), + do_need_mass_(true), + support_ms_(false), + fix_ms_(0), + ms_(0), + idregion_(0), + region_(0), + iregion_(-1) +{ +} + +/* ---------------------------------------------------------------------- */ + +FixBaseLiggghts::~FixBaseLiggghts() +{ + if(idregion_) delete []idregion_; +} + +/* ---------------------------------------------------------------------- */ + +void FixBaseLiggghts::process_region(char *regid) +{ + iregion_ = domain->find_region(regid); + if (iregion_ == -1) + error->fix_error(FLERR,this,"Region ID does not exist"); + int n = strlen(regid) + 1; + idregion_ = new char[n]; + strcpy(idregion_,regid); + region_ = domain->regions[iregion_]; +} + +/* ---------------------------------------------------------------------- */ + +void FixBaseLiggghts::init() +{ + // error checks + if (do_need_radius_ && !atom->radius_flag) + error->fix_error(FLERR,this,"requires atom attribute radius (per-particle)"); + + // error checks + if (do_need_mass_ && !atom->rmass_flag) + error->fix_error(FLERR,this,"requires atom attribute mass (per-particle)"); + + // check validity of region + iregion_ = -1; + if (idregion_) + { + iregion_ = domain->find_region(idregion_); + if (iregion_ == -1) + error->fix_error(FLERR,this,"Region ID does not exist"); + region_ = domain->regions[iregion_]; + } + + // multisphere support + + fix_ms_ = static_cast<FixMultisphere*>(modify->find_fix_style_strict("multisphere",0)); + if(modify->n_fixes_style("multisphere") > 1) + error->fix_error(FLERR,this,"does not support more than one fix multisphere."); + if(fix_ms_) + ms_ = &(fix_ms_->data()); + else + ms_ = 0; + + if(!support_ms_ && ms_) + error->fix_error(FLERR,this,"does not support multi-sphere"); + + // currently no groups for MS + int igrp_all = group->find("all"); + if(fix_ms_ && (igrp_all!= igroup)) + error->fix_error(FLERR,this,"does only support fix group 'all' when multi-sphere particles present"); + + if (strstr(update->integrate_style,"respa")) + nlevels_respa_ = ((Respa *) update->integrate)->nlevels; +} + +/* ---------------------------------------------------------------------- */ + +void FixBaseLiggghts::setup(int vflag) +{ + if (strstr(update->integrate_style,"verlet")) + post_force(vflag); + else + { + if(!support_respa_) + error->fix_error(FLERR,this,"does nor support run_style respa"); + ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa_-1); + post_force_respa(vflag,nlevels_respa_-1,0); + ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa_-1); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixBaseLiggghts::count_eligible(double &mass_counted,double &volume_counted, int &nparticles_counted) +{ + int nlocal = atom->nlocal; + int nbody_local = ms_? ms_->n_body() : 0; + int *mask = atom->mask; + double **x = atom->x; + double *rmass = atom->rmass; + double *radius = atom->radius; + mass_counted = 0.; + volume_counted = 0.; + nparticles_counted = 0.; + + double _4_pi_over_3 = 4.*M_PI/3.; + + // spheres contribution + + for(int ilocal = 0; ilocal < nlocal; ilocal++) + { + if (mask[ilocal] & groupbit) + { + // do not handle multi-sphere case + // skip if not in region + if ( + (!fix_ms_ || fix_ms_->belongs_to(ilocal) < 0) && + (!region_ || region_->match(x[ilocal][0],x[ilocal][1],x[ilocal][2])) + ) + { + mass_counted += rmass[ilocal]; + volume_counted += _4_pi_over_3*radius[ilocal]*radius[ilocal]*radius[ilocal]; + nparticles_counted += 1; + } + } + } + + // multi-spheres contribution + + for(int ibody_local = 0; ibody_local < nbody_local ; ibody_local++) + { + double xcm[3]; + ms_->xcm(xcm,ibody_local); + + // skip if not in region; group not accounted for here + if (!region_ || region_->match(xcm[0],xcm[1],xcm[2])) + { + mass_counted += ms_->mass(ibody_local); + volume_counted += ms_->volume(ibody_local); + nparticles_counted += 1; + } + } + + double vec_mpi[3]; + vec_mpi[0] = mass_counted; + vec_mpi[1] = volume_counted; + vec_mpi[2] = static_cast<double>(nparticles_counted); + MPI_Sum_Vector(vec_mpi,3,world); + mass_counted = vec_mpi[0]; + volume_counted = vec_mpi[1]; + nparticles_counted = static_cast<int>(vec_mpi[2]); +} diff --git a/src/fix_base_liggghts.h b/src/fix_base_liggghts.h new file mode 100644 index 0000000000000000000000000000000000000000..a46c44d12866d112535a693301415c99cff14fb6 --- /dev/null +++ b/src/fix_base_liggghts.h @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2015- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +//non-constructable + +#else + +#ifndef LMP_FIX_BASE_LIGGGHTS_H +#define LMP_FIX_BASE_LIGGGHTS_H + +#include "fix.h" +#include "container.h" +#include "region.h" + +namespace LAMMPS_NS { + +class FixBaseLiggghts : public Fix { + + public: + + FixBaseLiggghts(class LAMMPS *, int, char **); + virtual ~FixBaseLiggghts(); + + void process_region(char *regid); + + virtual void init(); + virtual void setup(int vflag); + + void do_support_multisphere() + { support_ms_ = true; } + + void do_support_respa() + { support_respa_ = true; } + + void do_not_need_radius() + { do_need_radius_ = false; } + + void do_not_need_mass() + { do_need_mass_ = false; } + + inline Region *region() + {return region_;} + + protected: + + void count_eligible(double &mass_counted,double &volume_counted, int &nparticles_counted); + + bool support_respa_; + int nlevels_respa_; + + bool do_need_radius_; + bool do_need_mass_; + + bool support_ms_; + class FixMultisphere *fix_ms_; + class Multisphere *ms_; + + // region to be used for replacement + char *idregion_; + class Region *region_; + int iregion_; +}; + +} + +#endif +#endif diff --git a/src/fix_buoyancy.cpp b/src/fix_buoyancy.cpp index 1e756dee453eb0e52f3a7114c4523beac0a8b205..a5424c11cf1c9325ade449ce373177bb9dd161bd 100644 --- a/src/fix_buoyancy.cpp +++ b/src/fix_buoyancy.cpp @@ -61,10 +61,8 @@ using namespace FixConst; /* ---------------------------------------------------------------------- */ FixBuoyancy::FixBuoyancy(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), + FixBaseLiggghts(lmp, narg, arg), density_(0.), - iregion_(-1), - id_region_(0), dim_(-1), direction_(1.), fluid_level_(0.), @@ -73,6 +71,8 @@ FixBuoyancy::FixBuoyancy(LAMMPS *lmp, int narg, char **arg) : { vectorZeroize3D(buyoancy_force_total_); + do_support_respa(); + if (narg < 3) error->fix_error(FLERR,this,"not enough arguments"); vector_flag = 1; @@ -109,12 +109,7 @@ FixBuoyancy::FixBuoyancy(LAMMPS *lmp, int narg, char **arg) : iarg += 2; } else if (strcmp(arg[iarg],"region") == 0) { if (iarg+2 > narg) error->fix_error(FLERR,this,"not enough arguments for 'region'"); - iregion_ = domain->find_region(arg[iarg+1]); - if (iregion_ == -1) - error->fix_error(FLERR,this,"region ID does not exist"); - int n = strlen(arg[iarg+1]) + 1; - id_region_ = new char[n]; - strcpy(id_region_,arg[iarg+1]); + process_region(arg[iarg+1]); iarg += 2; } else error->fix_error(FLERR,this," expecting 'density' or 'region'"); } @@ -131,7 +126,6 @@ FixBuoyancy::FixBuoyancy(LAMMPS *lmp, int narg, char **arg) : FixBuoyancy::~FixBuoyancy() { - if(id_region_) delete []id_region_; } /* ---------------------------------------------------------------------- */ @@ -149,22 +143,11 @@ int FixBuoyancy::setmask() void FixBuoyancy::init() { - if(!atom->radius_flag) - error->fix_error(FLERR,this,"requires per-atom radius"); + FixBaseLiggghts::init(); + if(!atom->density_flag) error->fix_error(FLERR,this,"requires per-atom density"); - if (strstr(update->integrate_style,"respa")) - nlevels_respa = ((Respa *) update->integrate)->nlevels; - - // set index and check validity of region - - if (iregion_ >= 0) { - iregion_ = domain->find_region(id_region_); - if (iregion_ == -1) - error->fix_error(FLERR,this,"region ID does not exist"); - } - if(1 != modify->n_fixes_style_strict("gravity")) error->fix_error(FLERR,this,"need exactly one fix gravity"); @@ -199,13 +182,7 @@ void FixBuoyancy::test_direction() void FixBuoyancy::setup(int vflag) { - if (strstr(update->integrate_style,"verlet")) - post_force(vflag); - else { - ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1); - post_force_respa(vflag,nlevels_respa-1,0); - ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1); - } + FixBaseLiggghts::setup(vflag); // error checks on coarsegraining if(force->cg_active()) @@ -251,8 +228,7 @@ void FixBuoyancy::post_force(int vflag) for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { - if (iregion_ >= 0 && - !domain->regions[iregion_]->match(x[i][0],x[i][1],x[i][2])) + if (region_ && !region_->match(x[i][0],x[i][1],x[i][2])) continue; double h = (x[i][dim_] - fluid_level_)*direction_; diff --git a/src/fix_buoyancy.h b/src/fix_buoyancy.h index 0840d5c888de2784f838c05f83e80e0c338ec747..51b6497474bd0340a87da503cd131d2e76c80c5b 100644 --- a/src/fix_buoyancy.h +++ b/src/fix_buoyancy.h @@ -47,11 +47,11 @@ FixStyle(buoyancy,FixBuoyancy) #ifndef LMP_FIX_BUOYANCY_H #define LMP_FIX_BUOYANCY_H -#include "fix.h" +#include "fix_base_liggghts.h" namespace LAMMPS_NS { -class FixBuoyancy : public Fix { +class FixBuoyancy : public FixBaseLiggghts { public: @@ -74,10 +74,6 @@ class FixBuoyancy : public Fix { double density_; int nlevels_respa; - // fluid region - int iregion_; - char *id_region_; - // fluid level int dim_; double direction_; diff --git a/src/fix_cfd_coupling_convection_impl.cpp b/src/fix_cfd_coupling_convection_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59fc1ce29692445a33447628d5458802a8ee07d2 --- /dev/null +++ b/src/fix_cfd_coupling_convection_impl.cpp @@ -0,0 +1,294 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + + Christoph Kloss (DCS Computing GmbH, Linz) + Stefan Radl (TU Graz) + + Copyright 2015- DCS Computing GmbH, Linz + Copyright 2015- TU Graz +------------------------------------------------------------------------- */ + +#include "string.h" +#include "stdlib.h" +#include "atom.h" +#include "update.h" +#include "respa.h" +#include "error.h" +#include "memory.h" +#include "modify.h" +#include "group.h" +#include "comm.h" +#include "math.h" +#include "vector_liggghts.h" +#include "fix_cfd_coupling_convection_impl.h" +#include "fix_property_atom.h" +#include "neighbor.h" +#include "fix_scalar_transport_equation.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixCfdCouplingConvectiveImpl::FixCfdCouplingConvectiveImpl(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) +{ + integrateHeatEqn_ = false; //default: DO NOT integrate heat equation, since we expect external program to do so + forceExplicit_ = false; //default: do not force explicit calculation, thus do implicit calculation + + fix_coupling = NULL; + fix_convectiveFlux = fix_heatFluid = fix_heatTransCoeff = NULL; + fix_heatFlux = NULL; + fix_temperature = NULL; + T0 = 0; + + int iarg = 3; + + if(narg >= iarg + 1) + { + if(strcmp(arg[iarg++],"integrateHeatEqn") != 0) + error->all(FLERR,"Fix couple/cfd/convectiveImpl: Expecting keyword 'integrateHeatEqn'"); + else + { + if(narg < iarg + 1) error->all(FLERR,"Fix couple/cfd/convectiveImpl: Wrong number of arguments after integrateHeatEqn. Provide 'true' or 'false' "); + + if(strcmp(arg[iarg],"false") == 0) + integrateHeatEqn_ = false; + else if (strcmp(arg[iarg],"true") == 0) + { + iarg++; + integrateHeatEqn_ = true; + if(strcmp(arg[iarg++],"T0") != 0) error->all(FLERR,"Fix couple/cfd/convectiveImpl: Expecting keyword 'T0'"); + if(narg < iarg+1) error->all(FLERR,"Fix couple/cfd/convectiveImpl: please specify a value after 'T0' "); + T0 = atof(arg[iarg++]); + } + else + error->all(FLERR,"Fix couple/cfd/convectiveImpl: Wrong argument after integrateHeatEqn. provide 'true' or 'false' "); + } + if(narg > iarg) + { + if(strcmp(arg[iarg++],"forceExplicit") == 0) + { + if(narg < iarg + 1) error->all(FLERR,"Fix couple/cfd/convectiveImpl: Wrong number of arguments after forceExplicit. provide 'true' or 'false' "); + + if(strcmp(arg[iarg],"false") == 0) + forceExplicit_ = false; + else if (strcmp(arg[iarg],"true") == 0) + { + iarg++; + forceExplicit_ = true; + } + else + error->all(FLERR,"Fix couple/cfd/convectiveImpl: Wrong argument after forceExplicit. provide 'true' or 'false' "); + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +FixCfdCouplingConvectiveImpl::~FixCfdCouplingConvectiveImpl() +{ +} + +/* ---------------------------------------------------------------------- */ + +void FixCfdCouplingConvectiveImpl::pre_delete(bool unfixflag) +{ + if(fix_heatFluid) modify->delete_fix("fix_heatFluid"); + if(fix_heatTransCoeff) modify->delete_fix("fix_heatTransCoeff"); + if(fix_convectiveFlux) modify->delete_fix("convectiveHeatFlux"); +} + +/* ---------------------------------------------------------------------- */ + +int FixCfdCouplingConvectiveImpl::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixCfdCouplingConvectiveImpl::post_create() +{ + // register fluid temperature and transfer coefficient + if(!fix_heatFluid) + { + const char* fixarg[11]; + fixarg[0]="heatFluid"; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]="heatFluid"; + fixarg[4]="scalar"; + fixarg[5]="no"; + fixarg[6]="yes"; + fixarg[7]="no"; + fixarg[8]="0."; + fix_heatFluid = modify->add_fix_property_atom(9,const_cast<char**>(fixarg),style); + } + + if(!fix_heatTransCoeff) + { + const char* fixarg[11]; + fixarg[0]="heatTransCoeff"; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]="heatTransCoeff"; + fixarg[4]="scalar"; + fixarg[5]="no"; + fixarg[6]="yes"; + fixarg[7]="no"; + fixarg[8]="0."; + fix_heatTransCoeff = modify->add_fix_property_atom(9,const_cast<char**>(fixarg),style); + } + + // register convective flux + if(!fix_convectiveFlux) + { + const char* fixarg[11]; + fixarg[0]="convectiveHeatFlux"; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]="convectiveHeatFlux"; + fixarg[4]="scalar"; + fixarg[5]="no"; + fixarg[6]="yes"; + fixarg[7]="no"; + fixarg[8]="0."; + fix_convectiveFlux = modify->add_fix_property_atom(9,const_cast<char**>(fixarg),style); + } + if(!integrateHeatEqn_) return; //this is usefil in case external tool performs integration + + // add heat transfer model if not yet active + FixScalarTransportEquation *fix_ste = modify->find_fix_scalar_transport_equation("heattransfer"); + if(!fix_ste) + { + const char *newarg[15]; + newarg[0] = "ste_heattransfer"; + newarg[1] = group->names[igroup]; + newarg[2] = "transportequation/scalar"; + newarg[3] = "equation_id"; + newarg[4] = "heattransfer"; + newarg[5] = "quantity"; + newarg[6] = "Temp"; + newarg[7] = "default_value"; + char arg8[30]; + sprintf(arg8,"%f",T0); + newarg[8] = arg8; + newarg[9] = "flux_quantity"; + newarg[10] = "heatFlux"; + newarg[11] = "source_quantity"; + newarg[12] = "heatSource"; + newarg[13] = "capacity_quantity"; + newarg[14] = "thermalCapacity"; + modify->add_fix(15,const_cast<char**>(newarg)); + } + fix_ste = modify->find_fix_scalar_transport_equation("heattransfer"); + + if(!forceExplicit_) + fix_ste->register_implicit_fixes((char *)"heatFluid", 0.0, (char *)"heatTransCoeff", 0); +} + +/* ---------------------------------------------------------------------- */ + +void FixCfdCouplingConvectiveImpl::init() +{ + // make sure there is only one fix of this style + if(modify->n_fixes_style(style) != 1) + error->all(FLERR,"More than one fix of style couple/cfd/convectiveImpl is not allowed"); + + // find coupling fix + fix_coupling = static_cast<FixCfdCoupling*>(modify->find_fix_style_strict("couple/cfd",0)); + if(!fix_coupling) + error->all(FLERR,"Fix couple/cfd/convectiveImpl needs a fix of type couple/cfd"); + + //values to send to OF, this is the SURFACE TEMPERATURE! + fix_coupling->add_push_property("Temp","scalar-atom"); + + //values to come from OF + fix_coupling->add_pull_property("heatFluid","scalar-atom"); + fix_coupling->add_pull_property("heatTransCoeff","scalar-atom"); + fix_coupling->add_pull_property("convectiveHeatFlux","scalar-atom"); + + fix_heatFluid = static_cast<FixPropertyAtom*>(modify->find_fix_property("heatFluid","property/atom","scalar",0,0,style)); + + fix_heatTransCoeff = static_cast<FixPropertyAtom*>(modify->find_fix_property("heatTransCoeff","property/atom","scalar",0,0,style)); + fix_convectiveFlux = static_cast<FixPropertyAtom*>(modify->find_fix_property("convectiveHeatFlux","property/atom","scalar",0,0,style)); + if(!integrateHeatEqn_) return; //only access heat flux if needed + + fix_heatFlux = static_cast<FixPropertyAtom*>(modify->find_fix_property("heatFlux","property/atom","scalar",0,0,style)); + fix_temperature = static_cast<FixPropertyAtom*>(modify->find_fix_property("Temp","property/atom","scalar",0,0,style)); +} + +/* ---------------------------------------------------------------------- */ +void FixCfdCouplingConvectiveImpl::post_force(int) +{ + // communicate convective flux to ghosts, there might be new data + if(0 == neighbor->ago) + { + fix_heatFluid->do_forward_comm(); + fix_heatTransCoeff->do_forward_comm(); + fix_convectiveFlux->do_forward_comm(); + } + + if(!integrateHeatEqn_) return; //only integrate if needed + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *Temp = fix_temperature->vector_atom; + double *convectiveFlux = fix_convectiveFlux->vector_atom; + + double *heatFlux = fix_heatFlux->vector_atom; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + heatFlux[i] += convectiveFlux[i]; + + if(!forceExplicit_) return; //only add implicit terms to heatFlux if necessary + + //Force explicit calculation by adding implicit part to (explicit) flux + double *radius = atom->radius; + double *heatFluid = fix_heatFluid->vector_atom; + double *heatTransCoeff = fix_heatTransCoeff->vector_atom; + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + { + double currRadius = radius[i]; + heatFlux[i] += heatTransCoeff[i] + * currRadius * currRadius * 12.5663706144 + * (heatFluid[i] - Temp[i]); //12.5663706144=4*pi + + } +} diff --git a/src/fix_cfd_coupling_convection_impl.h b/src/fix_cfd_coupling_convection_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..1f4f907e61059b95de04e6de336b0cfff224f627 --- /dev/null +++ b/src/fix_cfd_coupling_convection_impl.h @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + + Christoph Kloss (DCS Computing GmbH, Linz) + Stefan Radl (TU Graz) + + Copyright 2015- DCS Computing GmbH, Linz + Copyright 2015- TU Graz +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(couple/cfd/convectiveImpl,FixCfdCouplingConvectiveImpl) + +#else + +#ifndef LMP_FIX_CFD_COUPLING_CONVECTIVE_IMPL_H +#define LMP_FIX_CFD_COUPLING_CONVECTIVE_IMPL_H + +#include "fix_cfd_coupling.h" + +namespace LAMMPS_NS { + +class FixCfdCouplingConvectiveImpl : public Fix { + + public: + FixCfdCouplingConvectiveImpl(class LAMMPS *, int, char **); + ~FixCfdCouplingConvectiveImpl(); + void post_create(); + void pre_delete(bool unfixflag); + + virtual int setmask(); + virtual void init(); + virtual void post_force(int); + + protected: + bool integrateHeatEqn_; //set to true to activate integration of heat flux with a scalar transport equation + bool forceExplicit_; //force explicit calculation: i.e., aggregate all fluxes into heatFlux + class FixCfdCoupling* fix_coupling; + class FixPropertyAtom* fix_heatFluid; + class FixPropertyAtom* fix_heatTransCoeff; + class FixPropertyAtom* fix_convectiveFlux; + + class FixPropertyAtom* fix_temperature; //only needed in case heat integration is performed + class FixPropertyAtom* fix_heatFlux; //only needed in case heat integration is performed + double T0; +}; + +} + +#endif +#endif diff --git a/src/fix_cfd_coupling_convection_species.cpp b/src/fix_cfd_coupling_convection_species.cpp index d6e16895fa85ddca00b111f2581bf98a115f4d6b..dec892bc0b4324c15b8445dab705bc69aeebaba2 100644 --- a/src/fix_cfd_coupling_convection_species.cpp +++ b/src/fix_cfd_coupling_convection_species.cpp @@ -53,6 +53,8 @@ #include "vector_liggghts.h" #include "fix_cfd_coupling_convection_species.h" #include "fix_property_atom.h" +#include "fix_property_global.h" +#include "properties.h" using namespace LAMMPS_NS; using namespace FixConst; @@ -176,6 +178,17 @@ void FixCfdCouplingConvectionSpecies::post_create() FixScalarTransportEquation *fix_ste = modify->find_fix_scalar_transport_equation("speciesTransfer"); if(!fix_ste) { + int max_type = atom->get_properties()->max_type(); + Fix* capacityQty = modify->find_fix_property(capacityName_,"property/global","peratomtype",max_type,0,style,false); + + if(capacityQty==NULL) + { + sprintf(capacityName_, "none"); + if(comm->me==0) + printf("WARNING: FixCfdCouplingConvectionSpecies cannot locate capacity quantity. Thus, will assume you are not using capacity in scalar transport equation is '%s'.", capacityName_); + + } + const char *newarg[15]; newarg[0] = steName_; newarg[1] = group->names[igroup]; diff --git a/src/fix_cfd_coupling_force.cpp b/src/fix_cfd_coupling_force.cpp index da76d4b9ed6575e3ecba7b0d6cf4a28052479b24..843c446d484b9acb5121f8c21777571e3de99854 100644 --- a/src/fix_cfd_coupling_force.cpp +++ b/src/fix_cfd_coupling_force.cpp @@ -66,13 +66,18 @@ FixCfdCouplingForce::FixCfdCouplingForce(LAMMPS *lmp, int narg, char **arg) : Fi fix_volumeweight_(0), fix_dispersionTime_(0), fix_dispersionVel_(0), + fix_UrelOld_(0), use_force_(true), use_torque_(true), use_dens_(false), use_type_(false), use_stochastic_(false), + use_virtualMass_(false), + use_superquadric_(false), use_property_(false), - use_superquadric_(false) + use_fiber_topo_(false), + fix_fiber_axis_(0), + fix_fiber_ends_(0) { int iarg = 3; @@ -135,6 +140,20 @@ FixCfdCouplingForce::FixCfdCouplingForce(LAMMPS *lmp, int narg, char **arg) : Fi error->fix_error(FLERR,this,"expecting 'yes' or 'no' after 'transfer_stochastic'"); iarg++; hasargs = true; + } + else if(strcmp(arg[iarg],"transfer_virtualMass") == 0) + { + if(narg < iarg+2) + error->fix_error(FLERR,this,"not enough arguments for 'transfer_virtualMass'"); + iarg++; + if(strcmp(arg[iarg],"yes") == 0) + use_virtualMass_ = true; + else if(strcmp(arg[iarg],"no") == 0) + use_virtualMass_ = false; + else + error->fix_error(FLERR,this,"expecting 'yes' or 'no' after 'transfer_virtualMass'"); + iarg++; + hasargs = true; } else if(strcmp(arg[iarg],"transfer_property") == 0) { if(narg < iarg+5) error->fix_error(FLERR,this,"not enough arguments for 'transfer_type'"); @@ -148,6 +167,17 @@ FixCfdCouplingForce::FixCfdCouplingForce(LAMMPS *lmp, int narg, char **arg) : Fi sprintf(property_type,"%s",arg[iarg++]); iarg++; hasargs = true; + } else if(strcmp(arg[iarg],"transfer_fiber_topology") == 0) { + if(narg < iarg+2) + error->fix_error(FLERR,this,"not enough arguments for 'transfer_fiber_topology'"); + if(strcmp(arg[iarg],"yes") == 0) + use_fiber_topo_ = true; + else if(strcmp(arg[iarg],"no") == 0) + use_fiber_topo_ = false; + else + error->fix_error(FLERR,this,"expecting 'yes' or 'no' after 'transfer_fiber_topology'"); + iarg++; + hasargs = true; } else if(strcmp(arg[iarg],"transfer_superquadric") == 0) { if(narg < iarg+2) error->fix_error(FLERR,this,"not enough arguments for 'transfer_superquadric'"); @@ -267,10 +297,37 @@ void FixCfdCouplingForce::post_create() fixarg[6]="no"; // communicate ghost fixarg[7]="no"; // communicate rev fixarg[8]="0"; + fixarg[9]="0"; + fixarg[10]="0"; + fix_dispersionVel_ = modify->add_fix_property_atom(11,const_cast<char**>(fixarg),style); + } + + if(!fix_UrelOld_ && use_virtualMass_) + { + const char* fixarg[11]; + fixarg[0]="UrelOld"; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]="UrelOld"; + fixarg[4]="vector"; // vector per particle to be registered + fixarg[5]="yes"; // restart + fixarg[6]="no"; // communicate ghost + fixarg[7]="no"; // communicate rev + fixarg[8]="0"; fixarg[9]="0"; fixarg[10]="0"; fix_dispersionVel_ = modify->add_fix_property_atom(11,const_cast<char**>(fixarg),style); } + + if(use_fiber_topo_) + { + const char *fixarg[] = { + "topo", // fix id + "all", // fix group + "bond/fiber/topology" // fix style + }; + modify->add_fix(3,const_cast<char**>(fixarg)); + } } /* ---------------------------------------------------------------------- */ @@ -329,8 +386,14 @@ void FixCfdCouplingForce::init() if(use_stochastic_) { - fix_coupling_->add_pull_property("dispersionTime","scalar-atom"); - fix_coupling_->add_pull_property("dispersionVel","vector-atom"); + fix_coupling_->add_pull_property("dispersionTime","scalar-atom"); + fix_coupling_->add_pull_property("dispersionVel","vector-atom"); + } + + if(use_fiber_topo_) + { + fix_coupling_->add_pull_property("fiber_axis","vector-atom"); + fix_coupling_->add_pull_property("fiber_ends","vector-atom"); } vectorZeroize3D(dragforce_total); @@ -341,11 +404,12 @@ void FixCfdCouplingForce::init() } /* ---------------------------------------------------------------------- */ + void FixCfdCouplingForce::setup(int vflag) { if (strstr(update->integrate_style,"verlet")) post_force(vflag); - else + else error->fix_error(FLERR,this,"only 'run_style verlet' supported."); } diff --git a/src/fix_cfd_coupling_force.h b/src/fix_cfd_coupling_force.h index 09398e600071ff996b2b737c6e6cb3756e457525..0947af13e7ab3b69168160e34b6e30028decfea2 100644 --- a/src/fix_cfd_coupling_force.h +++ b/src/fix_cfd_coupling_force.h @@ -79,14 +79,23 @@ class FixCfdCouplingForce : public Fix { class FixPropertyAtom* fix_dispersionTime_; class FixPropertyAtom* fix_dispersionVel_; + + class FixPropertyAtom* fix_UrelOld_; + bool use_force_, use_torque_, use_dens_, use_type_; bool use_stochastic_; + bool use_virtualMass_; bool use_superquadric_; private: bool use_property_; char property_name[200]; char property_type[200]; + + bool use_fiber_topo_; + class FixPropertyAtom* fix_fiber_axis_; + class FixPropertyAtom* fix_fiber_ends_; + }; } diff --git a/src/fix_contact_history.cpp b/src/fix_contact_history.cpp index ad42bf7542cc215e84ce2ecf5988fc94342c55de..00b23fb54d0d4629ea198fc9f63759b2dd0862ff 100644 --- a/src/fix_contact_history.cpp +++ b/src/fix_contact_history.cpp @@ -102,8 +102,6 @@ FixContactHistory::FixContactHistory(LAMMPS *lmp, int narg, char **arg) : // initialize npartner to 0 so neighbor list creation is OK the 1st time - int nlocal = atom->nlocal; - std::fill_n(npartner_, atom->nmax, 0); //===================== @@ -215,20 +213,18 @@ void FixContactHistory::init() if(0 == strcmp(style,"contacthistory")) { - if(!force->pair_match("gran", 0)) - error->fix_error(FLERR,this,"Please use a granular pair style for fix contacthistory"); - pair_gran_ = static_cast<PairGran*>(force->pair_match("gran", 0)); - - if(dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair()) - { - pair_gran_ = static_cast<PairGran*>(force->pair_match("bubble", 0)); + + pair_gran_ = static_cast<PairGran*>(force->pair_match("gran", 1)); - if(! pair_gran_ || dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair()) - pair_gran_ = static_cast<PairGran*>(force->pair_match("gran_bubble", 0)); + if(!pair_gran_ || dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair()) + pair_gran_ = static_cast<PairGran*>(force->pair_match("gran_bubble", 1)); + if(!pair_gran_ || dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair()) + pair_gran_ = static_cast<PairGran*>(force->pair_match("bubble", 1)); - if(!pair_gran_ || (dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair())) - pair_gran_ = static_cast<PairGran*>(force->pair_match("gran", 0)); //at last, it must be a granular one! This is the case, e.g., in case extra history is used for liquid tracking - } + if(!pair_gran_) + error->fix_error(FLERR,this,"Please use a pair style 'gran', 'gran_bubble' or 'bubble' for fix contacthistory"); + if(dnum_ != static_cast<PairGran*>(pair_gran_)->dnum_pair()) + error->fix_error(FLERR,this,"internal error"); int dim; computeflag_ = (int *) pair_gran_->extract("computeflag",dim); @@ -307,12 +303,12 @@ void FixContactHistory::pre_exchange() // nlocal may include atoms added since last neigh build - int nlocal = atom->nlocal; + int nmax = atom->nmax; // zero npartner for all current atoms // clear 2 page data structures - std::fill_n(npartner_, nlocal, 0); + std::fill_n(npartner_, nmax, 0); ipage_->reset(); dpage_->reset(); @@ -342,6 +338,7 @@ void FixContactHistory::pre_exchange() for (jj = 0; jj < jnum; jj++) { if (contact_flag[jj]) { + npartner_[i]++; j = jlist[jj]; j &= NEIGHMASK; @@ -367,7 +364,7 @@ void FixContactHistory::pre_exchange() // store atom IDs and shear history for my atoms // re-zero npartner to use as counter for all my atoms - std::fill_n(npartner_, nlocal, 0); + std::fill_n(npartner_, nmax, 0); for (ii = 0; ii < inum; ii++) { i = ilist[ii]; @@ -410,6 +407,7 @@ void FixContactHistory::pre_exchange() // set maxtouch = max # of partners of any owned atom // bump up comm->maxexchange_fix if necessary maxtouch_ = 0; + int nlocal = atom->nlocal; if(nlocal > 0) maxtouch_ = *std::max_element(npartner_, npartner_+nlocal); comm->maxexchange_fix = MAX(comm->maxexchange_fix,(dnum_+1)*maxtouch_+1); @@ -566,7 +564,7 @@ void FixContactHistory::restart(char *buf) double *list = (double *) buf; int unpack_dnum = static_cast<int> (list[n++]); - //int unpack_maxtouch = static_cast<int> (list[n++]); + int unpack_maxtouch = static_cast<int> (list[n++]); if(unpack_dnum != dnum_) error->fix_error(FLERR,this,"saved simulation state used different contact history model - can not restart"); diff --git a/src/fix_contact_history_mesh.cpp b/src/fix_contact_history_mesh.cpp index 4e92ed47d47f344ac1a22de5bd853b132c16dd30..bd833ca1ea99a87d25a38b3353279ac8bc92b8e9 100644 --- a/src/fix_contact_history_mesh.cpp +++ b/src/fix_contact_history_mesh.cpp @@ -72,7 +72,9 @@ FixContactHistoryMesh::FixContactHistoryMesh(LAMMPS *lmp, int narg, char **arg) ipage2_(0), dpage2_(0), keeppage_(0), + intersectpage_(0), keepflag_(0), + intersectflag_(0), mesh_(0), fix_neighlist_mesh_(0), fix_nneighs_(0), @@ -89,9 +91,12 @@ FixContactHistoryMesh::FixContactHistoryMesh(LAMMPS *lmp, int narg, char **arg) swap_ = new double[dnum_]; - // initial allocation of delflag + // initial allocation of keepflag keepflag_ = (bool **) memory->srealloc(keepflag_,atom->nmax*sizeof(bool *), "contact_history:keepflag"); + // initial allocation of intersectflag + intersectflag_ = (bool **) memory->srealloc(intersectflag_,atom->nmax*sizeof(bool *), + "contact_history:intersectflag"); } /* ---------------------------------------------------------------------- */ @@ -113,6 +118,14 @@ FixContactHistoryMesh::~FixContactHistoryMesh() delete [] keeppage_; keeppage_ = NULL; } + if(intersectpage_) { + for(int i = 0; i < numpages_; i++) { + delete intersectpage_[i]; + intersectpage_[i] = NULL; + } + delete [] intersectpage_; + intersectpage_ = NULL; + } ipage_ = 0; dpage_ = 0; @@ -120,6 +133,7 @@ FixContactHistoryMesh::~FixContactHistoryMesh() delete [] swap_; if(keepflag_) memory->sfree(keepflag_); + if(intersectflag_) memory->sfree(intersectflag_); } /* ---------------------------------------------------------------------- */ @@ -173,6 +187,14 @@ void FixContactHistoryMesh::allocate_pages() delete [] keeppage_; keeppage_ = NULL; } + if(intersectpage_) { + for(int i = 0; i < numpages_; i++) { + delete intersectpage_[i]; + intersectpage_[i] = NULL; + } + delete [] intersectpage_; + intersectpage_ = NULL; + } pgsize_ = neighbor->pgsize; oneatom_ = neighbor->oneatom; @@ -182,6 +204,7 @@ void FixContactHistoryMesh::allocate_pages() ipage2_ = new MyPage<int>[numpages_]; dpage2_ = new MyPage<double>[numpages_]; keeppage_ = new MyPage<bool>*[numpages_]; + intersectpage_ = new MyPage<bool>*[numpages_]; for (int i = 0; i < numpages_; i++) { ipage1_[i].init(oneatom_,pgsize_); dpage1_[i].init(oneatom_*MathExtraLiggghts::max(1,dnum_),pgsize_); @@ -196,11 +219,15 @@ void FixContactHistoryMesh::allocate_pages() // make sure page is allocated in memory near core keeppage_[tid] = new MyPage<bool>(); keeppage_[tid]->init(oneatom_,pgsize_); + intersecthpage_[tid] = new MyPage<bool>(); + intersectpage_[tid]->init(oneatom_,pgsize_); } #else for (int i = 0; i < numpages_; i++) { keeppage_[i] = new MyPage<bool>(); keeppage_[i]->init(oneatom_,pgsize_); + intersectpage_[i] = new MyPage<bool>(); + intersectpage_[i]->init(oneatom_,pgsize_); } #endif @@ -290,10 +317,15 @@ void FixContactHistoryMesh::pre_force(int dummy) return; build_neighlist_ = false; + int nall = atom->nlocal+atom->nghost; + int nlocal = atom->nlocal; + + for(int i = nlocal; i < nall; i++) + npartner_[i] = 0; + cleanUpContactJumps(); int nneighs_next; - int nlocal = atom->nlocal; int *partner_prev; double *contacthistory_prev; @@ -303,7 +335,7 @@ void FixContactHistoryMesh::pre_force(int dummy) ipage_next->reset(); dpage_next->reset(); - for (int i = 0; i < nlocal; i++) + for (int i = 0; i < nall; i++) { nneighs_next = fix_nneighs_->get_vector_atom_int(i); @@ -376,19 +408,21 @@ void FixContactHistoryMesh::sort_contacts() } /* ---------------------------------------------------------------------- - mark all contacts for deletion + mark all contacts for deletion, mark all as not intersecting ------------------------------------------------------------------------- */ void FixContactHistoryMesh::markAllContacts() { - int nlocal = atom->nlocal; + int nall = atom->nlocal+atom->nghost; keeppage_[0]->reset(true); + intersectpage_[0]->reset(false); - for(int i = 0; i < nlocal; i++) + for(int i = 0; i < nall; i++) { const int nneighs = fix_nneighs_->get_vector_atom_int(i); keepflag_[i] = keeppage_[0]->get(nneighs); - if (!keepflag_[i]) + intersectflag_[i] = intersectpage_[0]->get(nneighs); + if (!keepflag_[i] || !intersectflag_[i]) error->one(FLERR,"mesh contact history overflow, boost neigh_modify one"); } } @@ -401,6 +435,7 @@ void FixContactHistoryMesh::resetDeletionPage(int tid) { // keep pages are initalized with 0 (= false) keeppage_[tid]->reset(true); + intersectpage_[tid]->reset(false); } /* ---------------------------------------------------------------------- @@ -413,7 +448,8 @@ void FixContactHistoryMesh::markForDeletion(int tid, int ifrom, int ito) { const int nneighs = fix_nneighs_->get_vector_atom_int(i); keepflag_[i] = keeppage_[tid]->get(nneighs); - if (!keepflag_[i]) + intersectflag_[i] = intersectpage_[tid]->get(nneighs); + if (!keepflag_[i] || !intersectflag_[i]) error->one(FLERR,"mesh contact history overflow, boost neigh_modify one"); } } @@ -422,7 +458,7 @@ void FixContactHistoryMesh::markForDeletion(int tid, int ifrom, int ito) void FixContactHistoryMesh::cleanUpContacts() { - cleanUpContacts(0, atom->nlocal); + cleanUpContacts(0, atom->nlocal+atom->nghost); } /* ---------------------------------------------------------------------- */ @@ -446,6 +482,7 @@ void FixContactHistoryMesh::cleanUpContacts(int ifrom, int ito) } partner_[i][j] = -1; + intersectflag_[i][j] = false; vectorZeroizeN(&(contacthistory_[i][j*dnum_]),dnum_); } } @@ -457,10 +494,10 @@ void FixContactHistoryMesh::cleanUpContacts(int ifrom, int ito) void FixContactHistoryMesh::cleanUpContactJumps() { - int nlocal = atom->nlocal; + int nall = atom->nlocal+atom->nghost; int iTri; - for(int i = 0; i < nlocal; i++) + for(int i = 0; i < nall; i++) { int ipartner = 0; while (ipartner < npartner_[i]) @@ -478,6 +515,7 @@ void FixContactHistoryMesh::cleanUpContactJumps() { partner_[i][ipartner] = -1; + intersectflag_[i][ipartner] = false; vectorZeroizeN(&(contacthistory_[i][ipartner*dnum_]),dnum_); swap(i,ipartner,npartner_[i]-1,false); npartner_[i]--; @@ -493,9 +531,9 @@ void FixContactHistoryMesh::cleanUpContactJumps() void FixContactHistoryMesh::reset_history() { - int nlocal = atom->nlocal; + int nall = atom->nlocal+atom->nghost; - for(int i = 0; i < nlocal; i++) + for(int i = 0; i < nall; i++) { const int nneighs = fix_nneighs_->get_vector_atom_int(i); @@ -529,6 +567,8 @@ void FixContactHistoryMesh::grow_arrays(int nmax) FixContactHistory::grow_arrays(nmax); keepflag_ = (bool **) memory->srealloc(keepflag_,nmax*sizeof(bool *), "contact_history:keepflag"); + intersectflag_ = (bool **) memory->srealloc(intersectflag_,nmax*sizeof(bool *), + "contact_history:keepflag"); } /* ---------------------------------------------------------------------- @@ -545,6 +585,7 @@ void FixContactHistoryMesh::copy_arrays(int i, int j, int delflag) FixContactHistory::copy_arrays(i,j,delflag); keepflag_[j] = keepflag_[i]; + intersectflag_[j] = intersectflag_[i]; } /* ---------------------------------------------------------------------- @@ -655,6 +696,7 @@ double FixContactHistoryMesh::memory_usage() bytes += ipage2_[i].size(); bytes += dpage2_[i].size(); bytes += keeppage_[i]->size(); + bytes += intersectpage_[i]->size(); } return bytes; diff --git a/src/fix_contact_history_mesh.h b/src/fix_contact_history_mesh.h index 67da686393d175bdd388e163e6798836a8370f44..e6816bb380cecf3e1ead011ea66b5de37a4d1bbb 100644 --- a/src/fix_contact_history_mesh.h +++ b/src/fix_contact_history_mesh.h @@ -91,7 +91,7 @@ class FixContactHistoryMesh : public FixContactHistory { // spefific interface for mesh - bool handleContact(int iPart, int idTri, double *&history); + bool handleContact(int iPart, int idTri, double *&history, bool intersectflag,bool faceflag); void markAllContacts(); void cleanUpContacts(); void cleanUpContactJumps(); @@ -114,18 +114,21 @@ class FixContactHistoryMesh : public FixContactHistory { MyPage<int> *ipage2_; // pages of neighbor tri IDs MyPage<double> *dpage2_; // pages of contact history with neighbors MyPage<bool> ** keeppage_; // pages of deletion flags with neighbors + MyPage<bool> ** intersectpage_; // pages of deletion flags with neighbors - bool **keepflag_; + bool **keepflag_; + + bool **intersectflag_; void allocate_pages(); private: // functions specific for mesh - contact management - bool haveContact(int indexPart, int idTri, double *&history); + bool haveContact(int indexPart, int idTri, double *&history,bool intersectflag); bool coplanarContactAlready(int indexPart, int idTri); void checkCoplanarContactHistory(int indexPart, int idTri, double *&history); - void addNewTriContactToExistingParticle(int indexPart, int idTri, double *&history); + void addNewTriContactToExistingParticle(int indexPart, int idTri, double *&history,bool intersectflag); class TriMesh *mesh_; class FixNeighlistMesh *fix_neighlist_mesh_; diff --git a/src/fix_contact_history_mesh_I.h b/src/fix_contact_history_mesh_I.h index 3ded06e18c64d4e7fbb959a7031763a77b16bf75..375f8009ff8e275083df30949e58e6f557334808 100644 --- a/src/fix_contact_history_mesh_I.h +++ b/src/fix_contact_history_mesh_I.h @@ -46,29 +46,35 @@ /* ---------------------------------------------------------------------- */ - inline bool FixContactHistoryMesh::handleContact(int iP, int idTri, double *&history) + inline bool FixContactHistoryMesh::handleContact(int iP, int idTri, double *&history,bool intersect,bool faceflag) { // check if contact with iTri was there before // if so, set history to correct location and return - if(haveContact(iP,idTri,history)) + if(haveContact(iP,idTri,history,intersect)) return true; // else new contact - add contact if did not calculate contact with coplanar neighbor already - if(coplanarContactAlready(iP,idTri)) + if(faceflag && coplanarContactAlready(iP,idTri)) + { // did not add new contact return false; + } else { - addNewTriContactToExistingParticle(iP,idTri,history); + /*if (coplanarContactAlready(iP,idTri) && !faceflag) + { + fprintf(screen,"WEIRD: atom ID %d, ts " BIGINT_FORMAT "\n",atom->tag[iP],update->ntimestep); + } + */ + addNewTriContactToExistingParticle(iP,idTri,history,intersect); // check if one of the contacts of previous steps is coplanar with iTri // if so, copy history - // also check if this contact has delflag = false, i.e. has been executed already - // this step. If so, signalize not to execute this contact (return false) - checkCoplanarContactHistory(iP,idTri,history); + if(faceflag) + checkCoplanarContactHistory(iP,idTri,history); return true; } } @@ -93,12 +99,16 @@ const bool keepflag_temp = keepflag_[ilocal][ineigh]; keepflag_[ilocal][ineigh] = keepflag_[ilocal][jneigh]; keepflag_[ilocal][jneigh] = keepflag_temp; + + const bool intersectflag_temp = intersectflag_[ilocal][ineigh]; + intersectflag_[ilocal][ineigh] = intersectflag_[ilocal][jneigh]; + intersectflag_[ilocal][jneigh] = intersectflag_temp; } } /* ---------------------------------------------------------------------- */ - inline bool FixContactHistoryMesh::haveContact(int iP, int idTri, double *&history) + inline bool FixContactHistoryMesh::haveContact(int iP, int idTri, double *&history,bool intersect) { int *tri = partner_[iP]; const int nneighs = fix_nneighs_->get_vector_atom_int(iP); @@ -109,6 +119,7 @@ { if(dnum_ > 0) history = &(contacthistory_[iP][i*dnum_]); keepflag_[iP][i] = true; + intersectflag_[iP][i] = intersect; return true; } } @@ -159,7 +170,7 @@ /* ---------------------------------------------------------------------- */ - inline void FixContactHistoryMesh::addNewTriContactToExistingParticle(int iP, int idTri, double *&history) + inline void FixContactHistoryMesh::addNewTriContactToExistingParticle(int iP, int idTri, double *&history, bool intersect) { const int nneighs = fix_nneighs_->get_vector_atom_int(iP); @@ -188,6 +199,7 @@ partner_[iP][iContact] = idTri; keepflag_[iP][iContact] = true; + intersectflag_[iP][iContact] = intersect; if(dnum_ > 0) { @@ -208,7 +220,15 @@ int ncontacts = 0, nlocal = atom->nlocal; for(int i = 0; i < nlocal; i++) - ncontacts += npartner_[i]; + { + for(int ipartner = 0; ipartner < npartner_[i]; ipartner++) + { + if(intersectflag_[i][ipartner]) + { + ncontacts++; + } + } + } return ncontacts; } @@ -220,8 +240,18 @@ int *mask = atom->mask; for(int i = 0; i < nlocal; i++) + { if(mask[i] & contact_groupbit) - ncontacts += npartner_[i]; + { + for(int ipartner = 0; ipartner < npartner_[i]; ipartner++) + { + if(intersectflag_[i][ipartner]) + { + ncontacts++; + } + } + } + } return ncontacts; } diff --git a/src/fix_heat_gran.h b/src/fix_heat_gran.h index cbbed736ce031315bb4848799be6e3110722a9c6..d6dc84aa91319c7430b04cd148f359e8d3d240b2 100644 --- a/src/fix_heat_gran.h +++ b/src/fix_heat_gran.h @@ -44,7 +44,7 @@ #include "fix.h" -#define SMALL 1e-8 +static const double SMALL_FIX_HEAT_GRAN = 1.e-6; namespace LAMMPS_NS { diff --git a/src/fix_heat_gran_conduction.cpp b/src/fix_heat_gran_conduction.cpp index 118f68e1c651ab40e344a9a58348f4fbdc75f532..e7eac8052bf5e707fedd3fe724215e6cf46f0345 100644 --- a/src/fix_heat_gran_conduction.cpp +++ b/src/fix_heat_gran_conduction.cpp @@ -356,7 +356,7 @@ void FixHeatGranCond::post_force_eval(int vflag,int cpl_flag) tcoi = conductivity_[type[i]-1]; tcoj = conductivity_[type[j]-1]; - if (tcoi < SMALL || tcoj < SMALL) hc = 0.; + if (tcoi < SMALL_FIX_HEAT_GRAN || tcoj < SMALL_FIX_HEAT_GRAN) hc = 0.; else hc = 4.*tcoi*tcoj/(tcoi+tcoj)*sqrt(contactArea); flux = (Temp[j]-Temp[i])*hc; diff --git a/src/fix_insert.cpp b/src/fix_insert.cpp index a82c2e236f8a11fe9062d7214e3a85c3da991d7d..6051ca11010dabe78261a7128587b8fd1006c777 100644 --- a/src/fix_insert.cpp +++ b/src/fix_insert.cpp @@ -77,7 +77,7 @@ using namespace FixConst; FixInsert::FixInsert(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), - neighList(*new RegionNeighborList(lmp)) + neighList(*new RegionNeighborList<interpolate_no>(lmp)) { if (narg < 7) error->fix_error(FLERR,this,"not enough arguments"); @@ -91,6 +91,8 @@ FixInsert::FixInsert(LAMMPS *lmp, int narg, char **arg) : fix_multisphere = NULL; multisphere = NULL; + compress_flag = false ; + // required args iarg = 3; @@ -114,6 +116,7 @@ FixInsert::FixInsert(LAMMPS *lmp, int narg, char **arg) : while(iarg < narg && hasargs) { hasargs = false; + if(strcmp(arg[iarg],"distributiontemplate") == 0) { if (iarg+2 > narg) error->fix_error(FLERR,this,""); int ifix = modify->find_fix(arg[iarg+1]); @@ -201,6 +204,16 @@ FixInsert::FixInsert(LAMMPS *lmp, int narg, char **arg) : else error->fix_error(FLERR,this,""); iarg += 2; hasargs = true; + } else if (strcmp(arg[iarg],"compress_tags") == 0) { + if (iarg+2 > narg) error->fix_error(FLERR,this,"not enough arguments for compress_tags"); + if(0 == strcmp(arg[iarg+1],"yes")) + compress_flag = true; + else if(0 == strcmp(arg[iarg+1],"no")) + compress_flag = false; + else + error->fix_error(FLERR,this,"expecting 'yes' or 'no' after 'compress_tags'"); + iarg += 2; + hasargs = true; } else if (strcmp(arg[iarg],"vel") == 0) { if (iarg+5 > narg) error->fix_error(FLERR,this,"not enough keyword for 'vel'"); if (strcmp(arg[iarg+1],"constant") == 0) { @@ -434,23 +447,23 @@ void FixInsert::print_stats_start() if(ninsert_exists) { if (screen) - fprintf(screen ,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f (mass rate %f)\n" - " %d particles (mass %f) within %d steps\n", + fprintf(screen ,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f (mass rate %e)\n" + " %d particles (mass %e) within %d steps\n", id,ninsert_per,insert_every,nflowrate,massflowrate,ninsert,massinsert,final_ins_step-first_ins_step); if (logfile) - fprintf(logfile,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f, (mass rate %f)\n" - " %d particles (mass %f) within %d steps\n", + fprintf(logfile,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f, (mass rate %e)\n" + " %d particles (mass %e) within %d steps\n", id,ninsert_per,insert_every,nflowrate,massflowrate,ninsert,massinsert,final_ins_step-first_ins_step); } else if(massflowrate > 0.) { if (screen) - fprintf(screen ,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f (mass rate %f)\n", + fprintf(screen ,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f (mass rate %e)\n", id,ninsert_per,insert_every,nflowrate,massflowrate); if (logfile) - fprintf(logfile,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f, (mass rate %f)\n", + fprintf(logfile,"INFO: Particle insertion %s: %f particles every %d steps - particle rate %f, (mass rate %e)\n", id,ninsert_per,insert_every,nflowrate,massflowrate); } else @@ -473,13 +486,13 @@ void FixInsert::print_stats_during(int ninsert_this, double mass_inserted_this) if (me == 0 && print_stats_during_flag) { if (screen) - fprintf(screen ,"INFO: Particle insertion %s: inserted %d particle templates (mass %f) at step " BIGINT_FORMAT "\n" - " - a total of %d particle templates (mass %f) inserted so far.\n", + fprintf(screen ,"INFO: Particle insertion %s: inserted %d particle templates (mass %e) at step " BIGINT_FORMAT "\n" + " - a total of %d particle templates (mass %e) inserted so far.\n", id,ninsert_this,mass_inserted_this,step,ninserted,massinserted); if (logfile) - fprintf(logfile,"INFO: Particle insertion %s: inserted %d particle templates (mass %f) at step " BIGINT_FORMAT "\n" - " - a total of %d particle templates (mass %f) inserted so far.\n", + fprintf(logfile,"INFO: Particle insertion %s: inserted %d particle templates (mass %e) at step " BIGINT_FORMAT "\n" + " - a total of %d particle templates (mass %e) inserted so far.\n", id,ninsert_this,mass_inserted_this,step,ninserted,massinserted); } } @@ -671,7 +684,7 @@ void FixInsert::pre_exchange() // fill xnear array with particles to check overlap against // add particles in insertion volume to xnear list - neighList.clear(); + neighList.reset(); if(check_ol_flag) load_xnear(ninsert_this_local); @@ -690,7 +703,7 @@ void FixInsert::pre_exchange() // actual particle insertion fix_distribution->pre_insert(ninserted_this_local,fix_property,fix_property_value); - + ninserted_spheres_this_local = fix_distribution->insert(ninserted_this_local); // warn if max # insertions exceeded by random processes @@ -702,9 +715,21 @@ void FixInsert::pre_exchange() // set tag # of new particles beyond all previous atoms, reset global natoms // if global map exists, reset it now instead of waiting for comm // since deleting atoms messes up ghosts + int step = update->ntimestep; if (atom->tag_enable) { + + //force all tags to be reset by setting them to zero + if(compress_flag) + { + if(comm->me == 0) + printf("FixInsertStream: resetting tags @ step %d. \n", step); + int *tag = atom->tag; + for (int i = 0; i < atom->nlocal; i++) + tag[i] = 0; + } + atom->tag_extend(); atom->natoms += static_cast<double>(ninserted_spheres_this); if (atom->map_style) @@ -855,7 +880,7 @@ int FixInsert::load_xnear(int ninsert_this_local) const int nall = atom->nlocal + atom->nghost; BoundingBox bb = getBoundingBox(); - neighList.clear(); + neighList.reset(); #ifdef SUPERQUADRIC_ACTIVE_FLAG neighList.set_obb_flag(check_obb_flag); #endif @@ -878,34 +903,6 @@ int FixInsert::load_xnear(int ninsert_this_local) } } -#ifdef SUPERQUADRIC_ACTIVE_FLAG - error->one(FLERR,"Sascha, please re-work this section; there were changes in the overlap detection algorithm" - //Sascha, your previous code is here: - - /*#ifdef SUPERQUADRIC_ACTIVE_FLAG - double **shape = atom->shape; - double **quat = atom->quaternion; - if(atom->superquadric_flag) - memory->create(xnear,nspheres_near_local + ninsert_this_local*fix_distribution->max_nspheres(), 11, "FixInsert::xnear"); - else - memory->create(xnear,nspheres_near_local + ninsert_this_local*fix_distribution->max_nspheres(), 4, "FixInsert::xnear"); - #else*/ - - //in the xnear loop, the code was: - /* - #ifdef SUPERQUADRIC_ACTIVE_FLAG - if(atom->superquadric_flag) { - xnear[ncount][4] = quat[i][0]; - xnear[ncount][5] = quat[i][1]; - xnear[ncount][6] = quat[i][2]; - xnear[ncount][7] = quat[i][3]; - xnear[ncount][8] = shape[i][0]; - xnear[ncount][9] = shape[i][1]; - xnear[ncount][10] = shape[i][2]; - } - #endif*/ -#endif - return neighList.count(); } diff --git a/src/fix_insert.h b/src/fix_insert.h index ce0819ee885e862aa2a8ba2735d94a289b829fe8..39292657f2dd255e84a734e80b76d0d9f8db39a9 100644 --- a/src/fix_insert.h +++ b/src/fix_insert.h @@ -147,7 +147,7 @@ class FixInsert : public Fix { int maxattempt; // positions generated, and for overlap check - RegionNeighborList &neighList; + RegionNeighborList<interpolate_no> &neighList; // velocity and ang vel distribution // currently constant for omega - could also be a distribution @@ -175,6 +175,9 @@ class FixInsert : public Fix { // warn if box extent too small for insertion bool warn_boxentent; + // compress atom tags upon insertion + bool compress_flag; + class FixMultisphere *fix_multisphere; class Multisphere *multisphere; diff --git a/src/fix_insert_pack.cpp b/src/fix_insert_pack.cpp index 62c1281271906322fad2b42acfa74a0c06ff542a..b5972a326b7ea674b60099a80bfdff9345663dcf 100644 --- a/src/fix_insert_pack.cpp +++ b/src/fix_insert_pack.cpp @@ -418,7 +418,7 @@ void FixInsertPack::x_v_omega(int ninsert_this_local,int &ninserted_this_local, pti = fix_distribution->pti_list[ninserted_this_local]; double rbound = pti->r_bound_ins; - if(print_stats_during_flag && (ninsert_this_local >= 10) && (0 == itotal % (ninsert_this_local/10))) + if(screen && print_stats_during_flag && (ninsert_this_local >= 10) && (0 == itotal % (ninsert_this_local/10))) fprintf(screen,"insertion: proc %d at %d %%\n",comm->me,10*itotal/(ninsert_this_local/10)); do @@ -460,7 +460,7 @@ void FixInsertPack::x_v_omega(int ninsert_this_local,int &ninserted_this_local, pti = fix_distribution->pti_list[ninserted_this_local]; double rbound = pti->r_bound_ins; - if(print_stats_during_flag && (ninsert_this_local >= 10) && (0 == ninserted_this_local % (ninsert_this_local/10)) ) + if(screen && print_stats_during_flag && (ninsert_this_local >= 10) && (0 == ninserted_this_local % (ninsert_this_local/10)) ) fprintf(screen,"insertion: proc %d at %d %%\n",comm->me,10*ninserted_this_local/(ninsert_this_local/10)); int nins = 0; diff --git a/src/fix_insert_stream.cpp b/src/fix_insert_stream.cpp index 9bf887cab9034fc97afb26f1ba548246053ab518..53cb54c9b18b0be9c4072d2957b91c1602cb03b1 100644 --- a/src/fix_insert_stream.cpp +++ b/src/fix_insert_stream.cpp @@ -84,6 +84,7 @@ FixInsertStream::FixInsertStream(LAMMPS *lmp, int narg, char **arg) : while(iarg < narg && hasargs) { hasargs = false; + if (strcmp(arg[iarg],"insertion_face") == 0) { @@ -786,7 +787,8 @@ void FixInsertStream::end_of_step() { if (mask[i] & groupbit) { - if(release_data[i][3] == 0.) continue; + if(MathExtraLiggghts::compDouble(release_data[i][3],0.,1.e-13)) + continue; i_step = static_cast<int>(release_data[i][3]+FIX_INSERT_STREAM_TINY); r_step = static_cast<int>(release_data[i][4]+FIX_INSERT_STREAM_TINY); diff --git a/src/fix_massflow_mesh.cpp b/src/fix_massflow_mesh.cpp index fb7639f90f9f4c01b374c2db3848804c8b6c39e2..68ade606ccccfd34b9b0ba439a303e4fe186bd48 100644 --- a/src/fix_massflow_mesh.cpp +++ b/src/fix_massflow_mesh.cpp @@ -236,15 +236,7 @@ FixMassflowMesh::FixMassflowMesh(LAMMPS *lmp, int narg, char **arg) : // get reference point on face // calculate normalvec - - fix_mesh_->triMesh()->node(0,0,pref_); - fix_mesh_->triMesh()->surfaceNorm(0,nvec_); - double dot = vectorDot3D(nvec_,sidevec_); - - if(fabs(dot) < 1e-6 && !havePointAtOutlet_ ) - error->fix_error(FLERR,this,"need to change 'vec_side', it is currently in or to close to the mesh plane"); - else if(dot < 0.) - vectorScalarMult3D(nvec_,-1.); + setRefPoint(); restart_global = 1; @@ -294,7 +286,9 @@ void FixMassflowMesh::post_create() if(fix_ms_) { ms_ = &fix_ms_->data(); - ms_counter_ = ms_->prop().addElementProperty< ScalarContainer<int> >("counter_ms","comm_exchange_borders","frame_invariant", "restart_yes"); + char property_name[200]; + sprintf(property_name,"counter_ms_%s",id); + ms_counter_ = ms_->prop().addElementProperty< ScalarContainer<int> >(static_cast<const char*>(property_name),"comm_exchange_borders","frame_invariant", "restart_yes"); ms_counter_->setDefaultValue(-1); if(delete_atoms_) @@ -366,7 +360,7 @@ void FixMassflowMesh::post_integrate() double *rmass = atom->rmass; int *mask = atom->mask; double *counter = fix_counter_->vector_atom; - double dot,delta[3]={}; + double dot,delta[3]={}, bary[3]; double mass_this = 0.; int nparticles_this = 0.; double property_this = 0.; @@ -383,6 +377,11 @@ void FixMassflowMesh::post_integrate() TriMesh *mesh = fix_mesh_->triMesh(); int nTriAll = mesh->sizeLocal() + mesh->sizeGhost(); + // update reference point + if (fix_mesh_->triMesh()->isMoving() || fix_mesh_->triMesh()->isDeforming()) { + setRefPoint(); + } + // update time for counter // also store values for last invokation t_count_ += update->dt; @@ -401,6 +400,7 @@ void FixMassflowMesh::post_integrate() const std::vector<int> & neighborList = fix_neighlist_->get_contact_list(iTri); const int numneigh = neighborList.size(); + for(int iNeigh = 0; iNeigh < numneigh; iNeigh++) { const int iPart = neighborList[iNeigh]; @@ -418,11 +418,11 @@ void FixMassflowMesh::post_integrate() // in case of once_ == true, ignore everything which has been already counted if((ibody > -1) ? ((*ms_counter_)(ibody) == 2) : (compDouble(counter[iPart],2.)) ) continue; + int barySign; + deltan = fix_mesh_->triMesh()->resolveTriSphereContactBary(iPart,iTri,radius[iPart],x[iPart],delta,bary,barySign); + if(havePointAtOutlet_) { - //get the vector from the particle center - //to the next triangle - deltan = fix_mesh_->triMesh()->resolveTriSphereContact(iPart,iTri,radius[iPart],x[iPart],delta); if(deltan < radius[iPart]) { vectorSubtract3D(x[iPart],pointAtOutlet_,nvec_); //vector pointing to the particle location @@ -451,7 +451,7 @@ void FixMassflowMesh::post_integrate() } // particle is now on nvec_ side - if(dot > 0.) + if(dot > 0. && 7 == barySign) { //particle was not on nvec_ side before if((ibody > -1) ? ((*ms_counter_)(ibody) == 0) : (compDouble(counter[iPart],0.)) ) // compDouble(counter[iPart],0.)) @@ -459,6 +459,7 @@ void FixMassflowMesh::post_integrate() mass_this += rmass[iPart]; nparticles_this ++; + if(fix_property_) { @@ -509,7 +510,7 @@ void FixMassflowMesh::post_integrate() counter[iPart] = once_ ? 2. : 1.; } - else // dot <= 0 + else if(dot <= 0.) // dot <= 0 { if(ibody > -1) (*ms_counter_)(ibody) = 0; @@ -652,3 +653,21 @@ double FixMassflowMesh::compute_vector(int index) return 0.; } + +/* ---------------------------------------------------------------------- + get reference point on face + calculate normalvec +------------------------------------------------------------------------- */ + +void FixMassflowMesh::setRefPoint() +{ + fix_mesh_->triMesh()->node(0,0,pref_); + fix_mesh_->triMesh()->surfaceNorm(0,nvec_); + double dot = vectorDot3D(nvec_,sidevec_); + + if(fabs(dot) < 1e-6 && !havePointAtOutlet_ ) + error->fix_error(FLERR,this,"need to change 'vec_side', it is currently in or to close to the mesh plane \n" + "This error may be caused by a moving mesh command, since 'vec_side' is not moved with the mesh."); + else if(dot < 0.) + vectorScalarMult3D(nvec_,-1.); +} diff --git a/src/fix_massflow_mesh.h b/src/fix_massflow_mesh.h index c479788b4af7ec59c43887de2ba5097f0eb7bda1..56049d107d7a69ade18c976016eb220bf3301349 100644 --- a/src/fix_massflow_mesh.h +++ b/src/fix_massflow_mesh.h @@ -96,6 +96,8 @@ class FixMassflowMesh : public Fix { class FixPropertyAtom *fix_counter_; private: + void setRefPoint(); + class FixMeshSurface *fix_mesh_; char fixid_[200]; class FixNeighlistMesh *fix_neighlist_; diff --git a/src/fix_mesh.cpp b/src/fix_mesh.cpp index b97c5e79cc6eea3954b69f4814898c7c9fbfd8c9..554e945002fa26af90e0800e8714eafadeabbdef 100644 --- a/src/fix_mesh.cpp +++ b/src/fix_mesh.cpp @@ -69,7 +69,7 @@ using namespace FixConst; #define EPSILON_V 0.00001 FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) -: Fix(lmp, narg, arg), +: FixBaseLiggghts(lmp, narg, arg), atom_type_mesh_(-1), mass_temperature_(0.), mesh_(NULL), @@ -79,6 +79,7 @@ FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) verbose_(false), autoRemoveDuplicates_(false), precision_(0.), + min_feature_length_(-1.), element_exclusion_list_(0), read_exclusion_list_(false), exclusion_list_(0), @@ -88,6 +89,10 @@ FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) if(narg < 5) error->fix_error(FLERR,this,"not enough arguments - at least keyword 'file' and a filename are required."); + do_support_multisphere(); + do_not_need_radius(); + do_not_need_mass(); + restart_global = 1; force_reneighbor = 1; @@ -123,6 +128,11 @@ FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) error->fix_error(FLERR,this,"expecing 'yes' or 'no' for 'verbose'"); iarg_ += 2; hasargs = true; + } else if (strcmp(arg[iarg_],"region") == 0) { + if (iarg_+2 > narg) error->fix_error(FLERR,this,"not enough arguments for 'region'"); + process_region(arg[iarg_+1]); + iarg_ += 2; + hasargs = true; } else if(strcmp(arg[iarg_],"heal") == 0) { if(narg < iarg_+2) error->fix_error(FLERR,this,"not enough arguments for 'heal'"); @@ -139,6 +149,13 @@ FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) if(precision_ < 0. || precision_ > 0.001) error->fix_error(FLERR,this,"0 < precision < 0.001 required"); hasargs = true; + } else if (strcmp(arg[iarg_],"min_feature_length") == 0) { + if (narg < iarg_+2) error->fix_error(FLERR,this,"not enough arguments"); + iarg_++; + min_feature_length_ = force->numeric(FLERR,arg[iarg_++]); + if(min_feature_length_ <= 0.) + error->fix_error(FLERR,this,"0 < min_feature_length > 0.0 required"); + hasargs = true; } else if (strcmp(arg[iarg_],"element_exclusion_list") == 0) { if (narg < iarg_+3) error->fix_error(FLERR,this,"not enough arguments"); iarg_++; @@ -172,6 +189,9 @@ FixMesh::FixMesh(LAMMPS *lmp, int narg, char **arg) } } + if(min_feature_length_ > 0. && (!element_exclusion_list_ || read_exclusion_list_)) + error->fix_error(FLERR,this,"'min_feature_length' requires use of 'element_exclusion_list write'"); + // create/handle exclusion list handle_exclusion_list(); @@ -320,6 +340,7 @@ void FixMesh::create_mesh(char *mesh_fname) if(verbose_) mesh_->setVerbose(); if(autoRemoveDuplicates_) mesh_->autoRemoveDuplicates(); if(precision_ > 0.) mesh_->setPrecision(precision_); + if(min_feature_length_ > 0.) mesh_->setMinFeatureLength(min_feature_length_); // read file // can be from STL file or VTK file @@ -329,7 +350,8 @@ void FixMesh::create_mesh(char *mesh_fname) if(!read_exclusion_list_ && element_exclusion_list_) mesh_->setElementExclusionList(element_exclusion_list_); - mesh_input->meshtrifile(mesh_fname,static_cast<TriMesh*>(mesh_),verbose_,size_exclusion_list_,exclusion_list_); + mesh_input->meshtrifile(mesh_fname,static_cast<TriMesh*>(mesh_),verbose_, + size_exclusion_list_,exclusion_list_,region_); delete mesh_input; } @@ -380,6 +402,8 @@ void FixMesh::pre_delete(bool unfixflag) void FixMesh::init() { + FixBaseLiggghts::init(); + if(mass_temperature_ > 0.) { int max_type = atom->get_properties()->max_type(); diff --git a/src/fix_mesh.h b/src/fix_mesh.h index 8745fc93c7441e1cfb36b62121b6f515d650b39f..5c8419f249132166f4406d9b6ca2ff229af86dde 100644 --- a/src/fix_mesh.h +++ b/src/fix_mesh.h @@ -48,11 +48,11 @@ #ifndef LMP_FIX_MESH_H #define LMP_FIX_MESH_H -#include "fix.h" +#include "fix_base_liggghts.h" namespace LAMMPS_NS { - class FixMesh : public Fix + class FixMesh : public FixBaseLiggghts { public: @@ -132,6 +132,9 @@ namespace LAMMPS_NS // mesh precision double precision_; + // ignore features smaller than this size + double min_feature_length_; + // mesh correction FILE *element_exclusion_list_; bool read_exclusion_list_; diff --git a/src/fix_multisphere.h b/src/fix_multisphere.h index 7347573178a01bc23e8b997385ff7a3f9c7a0c7e..d3749576009ce364000324902e189d7b315b4594 100644 --- a/src/fix_multisphere.h +++ b/src/fix_multisphere.h @@ -70,7 +70,8 @@ enum MS_COMM_FW_F_TORQUE, MS_COMM_REV_X_V_OMEGA, MS_COMM_REV_V_OMEGA, - MS_COMM_REV_IMAGE + MS_COMM_REV_IMAGE, + MS_COMM_REV_DISPLACE, }; class FixMultisphere : public Fix @@ -184,6 +185,15 @@ class FixMultisphere : public Fix bool allow_group_and_set() { return allow_group_and_set_; } + void scale_displace(int i, double factor) + { vectorScalarMult3D(displace_[i],factor); } + + inline void rev_comm_displace() + { + rev_comm_flag_ = MS_COMM_REV_DISPLACE; + reverse_comm(); + } + protected: inline int map(int i) diff --git a/src/fix_neighlist_mesh.cpp b/src/fix_neighlist_mesh.cpp index 204204c421a0027861f65781385a03fcde2cc178..52490f3e0df58707c237a025e7e297c172522a20 100644 --- a/src/fix_neighlist_mesh.cpp +++ b/src/fix_neighlist_mesh.cpp @@ -239,7 +239,7 @@ void FixNeighlistMesh::pre_force(int) numAllContacts_ = 0; // set num_neigh = 0 - memset(fix_nneighs_->vector_atom, 0, atom->nlocal*sizeof(double)); + memset(fix_nneighs_->vector_atom, 0, atom->nmax*sizeof(double)); x = atom->x; r = atom->radius; @@ -302,6 +302,60 @@ void FixNeighlistMesh::pre_force(int) /* ---------------------------------------------------------------------- */ +void FixNeighlistMesh::checkBin(AtomVecEllipsoid::Bonus *bonus, std::vector<int>& neighbors, int& nchecked, double contactDistanceFactor, int *mask, int nlocal, int iBin, int iTri, bool haveNonSpherical, int *ellipsoid, double *shape) +{ + int iAtom = binhead[iBin]; + + // only handle local atoms and periodic ghosts + while(iAtom != -1) + { + if((iAtom > nlocal) && (!domain->is_periodic_ghost(iAtom))) + { + if(bins) iAtom = bins[iAtom]; + else iAtom = -1; + + continue; + } + + if(! (mask[iAtom] & groupbit_wall_mesh)) + { + if(bins) iAtom = bins[iAtom]; + else iAtom = -1; + continue; + } + nchecked++; + + if(0) {} + #ifdef TRI_LINE_ACTIVE_FLAG + else if(haveNonSpherical) //if non-spherical, check line interaction as well + { + double *lineOrientation; //keep empty, not needed + double length; + double cylRadius; + shape = bonus[ellipsoid[iAtom]].shape; + length = 2.*MathExtraLiggghts::max(shape[0],shape[1],shape[2]); + cylRadius = MathExtraLiggghts::min(shape[0],shape[1],shape[2]); + if( mesh_->resolveTriSegmentNeighbuild(iTri, lineOrientation ,x[iAtom], length*contactDistanceFactor, cylRadius, skin ) ) + { + neighbors.push_back(iAtom); + fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ + } + } + #endif + else if(mesh_->resolveTriSphereNeighbuild(iTri,r ? r[iAtom]*contactDistanceFactor : 0. ,x[iAtom],r ? skin : (distmax+skin) )) + { + // include iAtom in neighbor list + neighbors.push_back(iAtom); + fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ + + } + if(bins) iAtom = bins[iAtom]; + else iAtom = -1; + } +} + +/* ---------------------------------------------------------------------- */ + void FixNeighlistMesh::handleTriangle(int iTri) { TriangleNeighlist & triangle = triangles[iTri]; @@ -335,48 +389,9 @@ void FixNeighlistMesh::handleTriangle(int iTri) for(int ix=ixMin;ix<=ixMax;ix++) { for(int iy=iyMin;iy<=iyMax;iy++) { for(int iz=izMin;iz<=izMax;iz++) { - int iBin = iz*mbiny*mbinx + iy*mbinx + ix; + const int iBin = iz*mbiny*mbinx + iy*mbinx + ix; if(iBin < 0 || iBin >= maxhead) continue; - - int iAtom = binhead[iBin]; - - while(iAtom != -1 && iAtom < nlocal) - { - if(! (mask[iAtom] & groupbit_wall_mesh)) - { - if(bins) iAtom = bins[iAtom]; - else iAtom = -1; - continue; - } - nchecked++; - - if(0) {} - #ifdef TRI_LINE_ACTIVE_FLAG - else if(haveNonSpherical) //if non-spherical, check line interaction as well - { - double *lineOrientation; //keep empty, not needed - double length; - double cylRadius; - shape = bonus[ellipsoid[iAtom]].shape; - length = 2.*MathExtraLiggghts::max(shape[0],shape[1],shape[2]); - cylRadius = MathExtraLiggghts::min(shape[0],shape[1],shape[2]); - if( mesh_->resolveTriSegmentNeighbuild(iTri, lineOrientation ,x[iAtom], length*contactDistanceFactor, cylRadius, skin ) ) - { - neighbors.push_back(iAtom); - fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ - } - } - #endif - else if(mesh_->resolveTriSphereNeighbuild(iTri,r ? r[iAtom]*contactDistanceFactor : 0. ,x[iAtom],r ? skin : (distmax+skin) )) - { - - neighbors.push_back(iAtom); - fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ - - } - if(bins) iAtom = bins[iAtom]; - else iAtom = -1; - } + checkBin(bonus, neighbors, nchecked, contactDistanceFactor, mask, nlocal, iBin, iTri, haveNonSpherical, ellipsoid, shape); } } } @@ -385,44 +400,7 @@ void FixNeighlistMesh::handleTriangle(int iTri) const int bincount = triangleBins.size(); for(int i = 0; i < bincount; i++) { const int iBin = triangleBins[i]; - - int iAtom = binhead[iBin]; - while(iAtom != -1 && iAtom < nlocal) - { - if(! (mask[iAtom] & groupbit_wall_mesh)) - { - if(bins) iAtom = bins[iAtom]; - else iAtom = -1; - continue; - } - nchecked++; - - if(0) {} - #ifdef TRI_LINE_ACTIVE_FLAG - else if(haveNonSpherical) //if non-spherical, check line interaction as well - { - double *lineOrientation; //keep empty, not needed - double length; - double cylRadius; - shape = bonus[ellipsoid[iAtom]].shape; - length = 2.*MathExtraLiggghts::max(shape[0],shape[1],shape[2]); - cylRadius = MathExtraLiggghts::min(shape[0],shape[1],shape[2]); - if( mesh_->resolveTriSegmentNeighbuild(iTri, lineOrientation ,x[iAtom], length*contactDistanceFactor, cylRadius, skin ) ) - { - neighbors.push_back(iAtom); - fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ - } - } - #endif - else if(mesh_->resolveTriSphereNeighbuild(iTri,r ? r[iAtom]*contactDistanceFactor : 0. ,x[iAtom],r ? skin : (distmax+skin) )) - { - - neighbors.push_back(iAtom); - fix_nneighs_->set_vector_atom_int(iAtom, fix_nneighs_->get_vector_atom_int(iAtom)+1); // num_neigh++ - } - if(bins) iAtom = bins[iAtom]; - else iAtom = -1; - } + checkBin(bonus, neighbors, nchecked, contactDistanceFactor, mask, nlocal, iBin, iTri, haveNonSpherical, ellipsoid, shape); } } } diff --git a/src/fix_neighlist_mesh.h b/src/fix_neighlist_mesh.h index 942c21ccdd55f1f959949b811b2fb1c4923aa9a7..5f17d52258e3b32bda2bb62424880144b25c1348 100644 --- a/src/fix_neighlist_mesh.h +++ b/src/fix_neighlist_mesh.h @@ -53,6 +53,7 @@ FixStyle(neighlist/mesh,FixNeighlistMesh) #include "fix.h" #include "container.h" +#include "atom_vec_ellipsoid.h" #include <vector> #include <algorithm> @@ -160,6 +161,8 @@ class FixNeighlistMesh : public Fix class AtomVecEllipsoid *avec; bool otherList_; +private: + void checkBin(AtomVecEllipsoid::Bonus *bonus, std::vector<int>& neighbors, int& nchecked, double contactDistanceFactor, int *mask, int nlocal, int iBin, int iTri, bool haveNonSpherical, int *ellipsoid, double *shape); }; } /* namespace LAMMPS_NS */ diff --git a/src/fix_particledistribution_discrete.cpp b/src/fix_particledistribution_discrete.cpp index 33259b978c78f1fd0860dd4b84e9df922504eb92..8688df215f16035e01c40ab535a46072d48a8415 100644 --- a/src/fix_particledistribution_discrete.cpp +++ b/src/fix_particledistribution_discrete.cpp @@ -44,6 +44,7 @@ #include "stdlib.h" #include "string.h" #include "fix_template_sphere.h" +#include "fix_template_multiplespheres.h" #include "fix_particledistribution_discrete.h" #include "atom.h" #include "atom_vec.h" @@ -474,6 +475,15 @@ void FixParticledistributionDiscrete::pre_insert(int n,class FixPropertyAtom *fp // loop to n, not n_pti if(fp) { + + for(int i = 0; i < ntemplates; i++) + { + if( dynamic_cast<FixTemplateMultiplespheres*>(templates[i]) && + dynamic_cast<FixTemplateMultiplespheres*>(templates[i])->is_bonded() + ) + error->one(FLERR,"'bonded' and setting values for a fix property upon insertion can not be used together"); + } + for(int i = 0; i < n; i++) { pti_list[i]->fix_property = fp; diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp index 430e1ba491b3a1fd3bee8cc0782f109c02a62bda..19446d2d46872bcf3d43d8aecb26db2d0c38c119 100644 --- a/src/fix_property_atom.cpp +++ b/src/fix_property_atom.cpp @@ -112,11 +112,12 @@ void FixPropertyAtom::parse_args(int narg, char **arg) else error->all(FLERR,"Unknown communicate_reverse_ghost style for fix property/atom. Valid styles are 'yes' or 'no'"); nvalues = narg - 8; + if ((nvalues == 1) && (data_style != FIXPROPERTY_ATOM_SCALAR)) error->all(FLERR,"Error in fix property/atom: Number of default values provided not consistent with vector style. Provide more than 1 value or use style 'scalar'"); if ((nvalues >1) && (data_style != FIXPROPERTY_ATOM_VECTOR)) - error->all(FLERR,"Error in fix property/atom: Number of default values provided not consistent with vector style. Provide 1 value or use style 'vector'"); + error->all(FLERR,"Error in fix property/atom: Number of default values provided not consistent with scalar style. Provide 1 value or use style 'vector'"); defaultvalues = new double[nvalues]; @@ -387,13 +388,18 @@ void FixPropertyAtom::set_arrays(int i) set all atoms values ------------------------------------------------------------------------- */ -void FixPropertyAtom::set_all(double value) +void FixPropertyAtom::set_all(double value, bool ghost) { - int nlocal = atom->nlocal; + int nall; + + if(!ghost) + nall = atom->nlocal; + else + nall = atom->nlocal + atom->nghost; if (data_style) { - for(int i = 0; i < nlocal; i++) + for(int i = 0; i < nall; i++) { for(int k=0;k<nvalues;k++) array_atom[i][k] = value; @@ -401,7 +407,7 @@ void FixPropertyAtom::set_all(double value) } else { - for(int i = 0; i < nlocal; i++) + for(int i = 0; i < nall; i++) vector_atom[i] = value; } } diff --git a/src/fix_property_atom.h b/src/fix_property_atom.h index 563d6dcc373611eadd37481cc6b4fd2ab7ed9b8b..666baa8827a555e6b62a0a84ad8f4603c1b4d161 100644 --- a/src/fix_property_atom.h +++ b/src/fix_property_atom.h @@ -81,7 +81,7 @@ class FixPropertyAtom : public Fix { void pre_set_arrays(); virtual void set_arrays(int); - void set_all(double value); + void set_all(double value,bool ghost = false); void write_restart(FILE *); virtual void restart(char *); @@ -109,6 +109,7 @@ class FixPropertyAtom : public Fix { int commGhost; // 1 if communicated to ghost particles (via pack_comm/unpack_comm), 0 if not int commGhostRev; // 1 if rev communicated from ghost particles (via pack_comm_rev/unpack_comm_rev), 0 if not int nvalues; + int nmaxGrown_; double *defaultvalues; // default values at particle creation // in case of initialization from property - name of property diff --git a/src/fix_property_atom_timetracer.cpp b/src/fix_property_atom_timetracer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d384f842ee49420c46c02c2d62c947fcc0b0a486 --- /dev/null +++ b/src/fix_property_atom_timetracer.cpp @@ -0,0 +1,232 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2013- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#include "math.h" +#include "stdlib.h" +#include "string.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "memory.h" +#include "error.h" +#include "group.h" +#include "region.h" +#include "domain.h" +#include "mpi_liggghts.h" +#include "math_extra_liggghts.h" +#include "fix_property_atom_timetracer.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +/* ---------------------------------------------------------------------- */ + +FixPropertyAtomTimeTracer::FixPropertyAtomTimeTracer(LAMMPS *lmp, int narg, char **arg,bool parse) : + FixPropertyAtom(lmp, narg, arg, false), + iarg_(3), + check_every_(10) +{ + // do the derived class stuff + + // parse args + + bool hasargs = true; + while(iarg_ < narg && hasargs) + { + hasargs = false; + + if(strcmp(arg[iarg_],"add_region") == 0) { + if(narg < iarg_+2) + error->fix_error(FLERR,this,"not enough arguments for 'add_region'"); + iarg_++; + int n = strlen(arg[iarg_]) + 1; + char *idreg = new char[n]; + strcpy(idreg,arg[iarg_]); + int ireg = domain->find_region(arg[iarg_++]); + if (ireg == -1) + error->fix_error(FLERR,this,"Region ID does not exist"); + iregion_.push_back(ireg); + idregion_.push_back(idreg); + hasargs = true; + } else if(strcmp(arg[iarg_],"check_region_every") == 0) { + if(narg < iarg_+2) + error->fix_error(FLERR,this,"not enough arguments for 'check_region_every'"); + iarg_++; + check_every_ = atoi(arg[iarg_]); + if(check_every_ < 0) + error->fix_error(FLERR,this,"check_region_every > 0 required"); + iarg_++; + hasargs = true; + } else if(strcmp(style,"property/atom/timetracer") == 0 ) + error->fix_error(FLERR,this,"unknown keyword"); + } + + // do the base class stuff + // allocate one extra per-particle for each region + + int n = strlen(id) + 1; + char *tracer_name = new char[n]; + strcpy(tracer_name,id); + int n_reg = iregion_.size(); + const char *baseargs[9+n_reg]; + baseargs[0] = tracer_name; + baseargs[1] = "all"; + baseargs[2] = "property/atom/tracer"; + baseargs[3] = tracer_name; + if(0 == n_reg) + baseargs[4] = "scalar"; + else + baseargs[4] = "vector"; + baseargs[5] = "yes"; + baseargs[6] = "yes"; + baseargs[7] = "no"; + baseargs[8] = "0."; + for(int i = 0; i < n_reg; i++) + baseargs[9+i] = "0."; + parse_args(9+n_reg,(char**)baseargs); + + // settings + nevery = check_every_; + + vector_flag = 1; + size_vector = 1+n_reg; + global_freq = check_every_; + extvector = 1; +} + +/* ---------------------------------------------------------------------- */ + +FixPropertyAtomTimeTracer::~FixPropertyAtomTimeTracer() +{ + for(size_t i = 0; i < idregion_.size(); i++) + delete [] idregion_[i]; +} + +/* ---------------------------------------------------------------------- + initialize this fix +------------------------------------------------------------------------- */ + +void FixPropertyAtomTimeTracer::init() +{ + iregion_.clear(); + for(size_t i = 0; i < idregion_.size(); i++) + { + int ireg = domain->find_region(idregion_[i]); + if (ireg == -1) + error->fix_error(FLERR,this,"Region ID does not exist"); + iregion_.push_back(ireg); + } + + int n_ms = modify->n_fixes_style("multisphere"); + if(n_ms > 0) + error->fix_error(FLERR,this,"may not be used together with fix multisphere"); +} + +/* ---------------------------------------------------------------------- */ + +int FixPropertyAtomTimeTracer::setmask() +{ + int mask = FixPropertyAtom::setmask(); + mask |= END_OF_STEP; + return mask; +} + +/* ---------------------------------------------------------------------- + add residence time(s) +------------------------------------------------------------------------- */ + +void FixPropertyAtomTimeTracer::end_of_step() +{ + int nlocal = atom->nlocal; + double **x = atom->x; + + // add multiple of dt in case check_region_every > 1 + double dt_this = static_cast<double>(check_every_)*update->dt; + int n_reg = iregion_.size(); + bool has_regions = n_reg > 0; + + if(!has_regions) + { + double *time = this->vector_atom; + for(int i = 0; i < nlocal; i++) + time[i] += dt_this; + } + else // has_regions + { + double **time = this->array_atom; + Region *region = 0; + + for(int i = 0; i < nlocal; i++) + { + time[i][0] += dt_this; + for(int ireg = 0; ireg < n_reg; ireg++) + { + region = domain->regions[iregion_[ireg]]; + if(region->match(x[i][0],x[i][1],x[i][2])) + time[i][1+ireg] += dt_this; + } + } + } +} + +/* ---------------------------------------------------------------------- + return average of residence time, n = 0..nvalues-1 +------------------------------------------------------------------------- */ + +double FixPropertyAtomTimeTracer::compute_vector(int n) +{ + int nlocal = atom->nlocal; + int *mask = atom->mask; + + double value = 0.; + + for (int i = 0; i < nlocal; i++) + { + if (mask[i] & groupbit) + { + if (array_atom) value += array_atom[i][n]; + else value += vector_atom[i]; + } + } + + MPI_Sum_Scalar(value,world); + return value/atom->natoms; +} diff --git a/src/rerun.h b/src/fix_property_atom_timetracer.h similarity index 68% rename from src/rerun.h rename to src/fix_property_atom_timetracer.h index d7bff75b8de5751d7d92a4a135b3612f269409df..3f90086fcdc9e29a849523f0eb9e81d6aa86ab0d 100644 --- a/src/rerun.h +++ b/src/fix_property_atom_timetracer.h @@ -32,56 +32,50 @@ ------------------------------------------------------------------------- Contributing author and copyright for this file: - This file is from LAMMPS - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. + (if no contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2013- DCS Computing GmbH, Linz ------------------------------------------------------------------------- */ -#ifdef COMMAND_CLASS +#ifdef FIX_CLASS -CommandStyle(rerun,Rerun) +FixStyle(property/atom/timetracer,FixPropertyAtomTimeTracer) #else -#ifndef LMP_RERUN_H -#define LMP_RERUN_H +#ifndef LMP_FIX_PROPERTY_ATOM_TIMETRACER_H +#define LMP_FIX_PROPERTY_ATOM_TIMETRACER_H -#include "pointers.h" +#include "fix_property_atom.h" +#include <vector> namespace LAMMPS_NS { -class Rerun : protected Pointers { - public: - Rerun(class LAMMPS *); - void command(int, char **); -}; +class FixPropertyAtomTimeTracer : public FixPropertyAtom { -} - -#endif -#endif + public: -/* ERROR/WARNING messages: + FixPropertyAtomTimeTracer(class LAMMPS *, int, char **, bool parse = true); + ~FixPropertyAtomTimeTracer(); -E: Rerun command before simulation box is defined + virtual void init(); + virtual int setmask(); + void end_of_step(); -The rerun command cannot be used before a read_data, read_restart, or -create_box command. + virtual double compute_vector(int n); -E: Illegal ... command + protected: -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. + int iarg_; -E: Rerun dump file does not contain requested snapshot + // params for region marker + std::vector<int> iregion_; + std::vector<char*> idregion_; -Self-explanatory. + double check_every_; +}; //end class -*/ +} +#endif +#endif diff --git a/src/fix_scalar_transport_equation.cpp b/src/fix_scalar_transport_equation.cpp index ae980831a496218fdf2d26375cb6de9a4a5f8aaa..99ad71003e38718c5fdc16cb483597228de48dbc 100644 --- a/src/fix_scalar_transport_equation.cpp +++ b/src/fix_scalar_transport_equation.cpp @@ -37,6 +37,10 @@ Copyright 2012- DCS Computing GmbH, Linz Copyright 2009-2012 JKU Linz + + Implementation of implicit update algorithm + Copyright 2016 TU Graz, Stefan Radl + Copyright 2016 DCS Computing GmbH, Linz ------------------------------------------------------------------------- */ #include "math.h" @@ -71,7 +75,32 @@ using namespace FixConst; FixScalarTransportEquation::FixScalarTransportEquation(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { - + fix_quantity = fix_flux = fix_source = NULL; fix_capacity = NULL; + fix_fluidQty_ = fix_transCoeffQty_ = NULL; + fluidQty_0_ = 0; + transCoeffQty_0_ = 0; + + capacity = NULL; + + int_flag = true; + + nevery_ = 1; + performedIntegrationLastStep_ = true; //ensure flux is reset at the very first time step + + peratom_flag = 1; + size_peratom_cols = 0; + peratom_freq = 1; + + scalar_flag = 1; + global_freq = 1; + + capacity_name = NULL; + capacity_flag = 0; + + crankNicholsonFactor_ = 0.5; //0 ... fully explicit; 1 ... fully implicit + implicitMode_ = false; + advanceQty=&FixScalarTransportEquation::advanceQtyExplicit; + if(strcmp(arg[2],"transportequation/scalar")) return; @@ -104,9 +133,6 @@ FixScalarTransportEquation::FixScalarTransportEquation(LAMMPS *lmp, int narg, ch source_name = new char[strlen(arg[iarg])+1]; strcpy(source_name,arg[iarg++]); - capacity_name = NULL; - capacity_flag = 0; - if(strcmp(arg[iarg++],"capacity_quantity")) error->fix_error(FLERR,this,"expecting keyword 'capacity_quantity'"); if(strcmp(arg[iarg],"none")) @@ -115,21 +141,6 @@ FixScalarTransportEquation::FixScalarTransportEquation(LAMMPS *lmp, int narg, ch capacity_name = new char[strlen(arg[iarg])+1]; strcpy(capacity_name,arg[iarg++]); } - - fix_quantity = fix_flux = fix_source = NULL; fix_capacity = NULL; - capacity = NULL; - - int_flag = true; - - nevery_ = 1; - performedIntegrationLastStep_ = true; //ensure flux is reset at the very first time step - - peratom_flag = 1; - size_peratom_cols = 0; - peratom_freq = 1; - - scalar_flag = 1; - global_freq = 1; } /* ---------------------------------------------------------------------- */ @@ -142,10 +153,75 @@ FixScalarTransportEquation::~FixScalarTransportEquation() delete []capacity_name; delete []equation_id; + if(implicitMode_) + { + delete []fluid_name_; + delete []transCoeff_name_; + } + if(capacity) delete []capacity; } +/* ---------------------------------------------------------------------- */ +void FixScalarTransportEquation::register_implicit_fixes(char* fluidName, double fluid0, char* transCoeffName, double transCoeff0) +{ + const char *fixarg[9]; + + implicitMode_ = true; + advanceQty=&FixScalarTransportEquation::advanceQtyImplicit; + + fluid_name_ = new char[strlen(fluidName)+1]; + strcpy(fluid_name_,fluidName); + fluidQty_0_ = fluid0; + + transCoeff_name_ = new char[strlen(transCoeffName)+1]; + strcpy(transCoeff_name_,transCoeffName); + transCoeffQty_0_ = transCoeff0; + + fix_fluidQty_=static_cast<FixPropertyAtom*>(modify->find_fix_property(fluid_name_,"property/atom","scalar",0,0,style)); + if (fix_fluidQty_==NULL) { + //register fluid quantity as property/atom + fixarg[0]=fluid_name_; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]=fluid_name_; + fixarg[4]="scalar"; + fixarg[5]="yes"; //restart + fixarg[6]="no"; //commGhost + fixarg[7]="yes"; //commGhostRev + char arg8[30]; + sprintf(arg8,"%e", fluidQty_0_); + fixarg[8]=arg8; + modify->add_fix(9,const_cast<char**>(fixarg)); + fix_fluidQty_=static_cast<FixPropertyAtom*>(modify->find_fix_property(fluid_name_,"property/atom","scalar",0,0,style)); + } + + fix_transCoeffQty_=static_cast<FixPropertyAtom*>(modify->find_fix_property(transCoeff_name_,"property/atom","scalar",0,0,style)); + if (fix_transCoeffQty_==NULL){ + //register transfer coefficient as property/atom + fixarg[0]=transCoeff_name_; + fixarg[1]="all"; + fixarg[2]="property/atom"; + fixarg[3]=transCoeff_name_; + fixarg[4]="scalar"; + fixarg[5]="yes"; //restart + fixarg[6]="no"; //commGhost + fixarg[7]="yes"; //commGhostRev + char arg8[30]; + sprintf(arg8,"%e", transCoeffQty_0_); + fixarg[8]=arg8; + modify->add_fix(9,const_cast<char**>(fixarg)); + fix_transCoeffQty_=static_cast<FixPropertyAtom*>(modify->find_fix_property(transCoeff_name_,"property/atom","scalar",0,0,style)); + } + + updatePtrsImpl(); + + return; +} + +/* ---------------------------------------------------------------------- */ + void FixScalarTransportEquation::pre_delete(bool unfixflag) { //unregister property/atom fixes @@ -154,6 +230,11 @@ void FixScalarTransportEquation::pre_delete(bool unfixflag) if (fix_quantity) modify->delete_fix(quantity_name); if (fix_flux) modify->delete_fix(flux_name); if (fix_source) modify->delete_fix(source_name); + if(implicitMode_) + { + if (fix_fluidQty_) modify->delete_fix(fluid_name_); + if (fix_transCoeffQty_) modify->delete_fix(transCoeff_name_); + } } } @@ -177,9 +258,19 @@ void FixScalarTransportEquation::updatePtrs() flux = fix_flux->vector_atom; source = fix_source->vector_atom; + if(implicitMode_) + updatePtrsImpl(); + vector_atom = quantity; } +/* ---------------------------------------------------------------------- */ +void FixScalarTransportEquation::updatePtrsImpl() +{ + fluidQty_ = fix_fluidQty_->vector_atom; + transCoeffQty_ = fix_transCoeffQty_->vector_atom; +} + /* ---------------------------------------------------------------------- */ void FixScalarTransportEquation::post_create() @@ -332,12 +423,6 @@ void FixScalarTransportEquation::pre_force(int vflag) void FixScalarTransportEquation::final_integrate() { - double dt = update->dt; - int nlocal = atom->nlocal; - double *rmass = atom->rmass; - int *type = atom->type; - int *mask = atom->mask; - double capacity; // skip if integration turned off if(!int_flag) @@ -354,6 +439,21 @@ void FixScalarTransportEquation::final_integrate() fix_source->do_forward_comm(); + (this->*advanceQty)(); + + performedIntegrationLastStep_ = true; +} + +/* ---------------------------------------------------------------------- */ +void FixScalarTransportEquation::advanceQtyExplicit() +{ + double dt = update->dt; + int nlocal = atom->nlocal; + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + double capacity; + if(capacity_flag) { for (int i = 0; i < nlocal; i++) @@ -380,7 +480,67 @@ void FixScalarTransportEquation::final_integrate() } } } - performedIntegrationLastStep_ = true; +} + +/* ---------------------------------------------------------------------- */ +void FixScalarTransportEquation::advanceQtyImplicit() +{ + + double dt = update->dt; + int nlocal = atom->nlocal; + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + double *radius = atom->radius; + double capacity; + double OneMinusCN = 1.0 - crankNicholsonFactor_; + + if(capacity_flag) + { + for (int i = 0; i < nlocal; i++) + { + if (mask[i] & groupbit){ + capacity = fix_capacity->compute_vector(type[i]-1); + if(fabs(capacity) > SMALL) + { + double currRadius = radius[i]; + double termM = dt / (rmass[i]*capacity); + double termMP = termM + * transCoeffQty_[i] + * currRadius * currRadius * 12.5663706144 ; //surface area + quantity[i] = ( quantity[i] + * (1.0 - termMP * OneMinusCN) + + termMP * fluidQty_[i] + + termM + * ( flux[i] + + source[i]*double(nevery_) + ) + ) / (1.0 + termMP*crankNicholsonFactor_); + } + } + } + } + else + { + for (int i = 0; i < nlocal; i++) + { + if (mask[i] & groupbit) + { + double currRadius = radius[i]; + double termMP = dt + * transCoeffQty_[i] + * currRadius * currRadius * 12.5663706144 ; //surface area + quantity[i] = ( quantity[i] + * (1.0 - termMP * OneMinusCN) + + termMP * fluidQty_[i] + + dt + * ( flux[i] + + source[i]*double(nevery_) + ) + ) / (1.0 + termMP*crankNicholsonFactor_); + } + } + } } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_scalar_transport_equation.h b/src/fix_scalar_transport_equation.h index 79c164cb6886a3573ff84118d958159c3e3ddcc9..c85970636850184c2ed5435a171e8dca6740cfa1 100644 --- a/src/fix_scalar_transport_equation.h +++ b/src/fix_scalar_transport_equation.h @@ -37,6 +37,10 @@ Copyright 2012- DCS Computing GmbH, Linz Copyright 2009-2012 JKU Linz + + Implementation of implicit update algorithm + Copyright 2016 TU Graz, Stefan Radl + Copyright 2016 DCS Computing GmbH, Linz ------------------------------------------------------------------------- */ #ifdef FIX_CLASS @@ -70,6 +74,11 @@ class FixScalarTransportEquation : public Fix { virtual double compute_scalar(); bool match_equation_id(const char*); + //Tools for implicit fix handling + bool isImplicit() { return implicitMode_;}; + void register_implicit_fixes(char*, double, char*, double); + void updatePtrsImpl(); + double *get_capacity(); inline int n_every() @@ -77,6 +86,10 @@ class FixScalarTransportEquation : public Fix { protected: + void (FixScalarTransportEquation::*advanceQty)(); + void advanceQtyExplicit(); + void advanceQtyImplicit(); + int nlevels_respa; char *equation_id; @@ -88,6 +101,18 @@ class FixScalarTransportEquation : public Fix { class FixPropertyAtom* fix_source; char *source_name; + //Implicit fixes, names, and pointers + double crankNicholsonFactor_; + bool implicitMode_; + class FixPropertyAtom* fix_fluidQty_; + char *fluid_name_; + class FixPropertyAtom* fix_transCoeffQty_; + char *transCoeff_name_; + double *fluidQty_; + double *transCoeffQty_; + double fluidQty_0_; + double transCoeffQty_0_; + //storage capacity - would be thermal capacity for heat conduction int capacity_flag; class FixPropertyGlobal* fix_capacity; diff --git a/src/fix_template_multiplespheres.cpp b/src/fix_template_multiplespheres.cpp index 17c58aa9da109c36871b93b35c2ddf5f344d85ea..061d82282a62557bea79837fd8ef44db8a0ffbf9 100644 --- a/src/fix_template_multiplespheres.cpp +++ b/src/fix_template_multiplespheres.cpp @@ -49,6 +49,7 @@ a Fortran version of the MC integrator #include "stdlib.h" #include "string.h" #include "fix_template_multiplespheres.h" +#include "fix_property_atom.h" #include "math_extra.h" #include "math_extra_liggghts.h" #include "vector_liggghts.h" @@ -58,6 +59,7 @@ a Fortran version of the MC integrator #include "modify.h" #include "comm.h" #include "force.h" +#include "update.h" #include "output.h" #include "memory.h" #include "error.h" @@ -97,6 +99,9 @@ FixTemplateMultiplespheres::FixTemplateMultiplespheres(LAMMPS *lmp, int narg, ch delete pti; pti = new ParticleToInsert(lmp,nspheres); + bonded = false; + fix_bond_random_id = 0; + for (int i = 0; i < 3; i++) { x_min[i] = LARGE; x_max[i] = -LARGE; @@ -130,7 +135,7 @@ FixTemplateMultiplespheres::FixTemplateMultiplespheres(LAMMPS *lmp, int narg, ch if (strcmp(arg[iarg],"file") == 0) { iarg++; - if (narg < iarg+3) error->fix_error(FLERR,this,"not enough arguments"); + if (narg < iarg+3) error->fix_error(FLERR,this,"not enough arguments for 'file'"); if(different_type) atom_type_sphere = new int[nspheres]; @@ -185,6 +190,18 @@ FixTemplateMultiplespheres::FixTemplateMultiplespheres(LAMMPS *lmp, int narg, ch } } } + else if(strcmp(arg[iarg],"bonded") == 0) + { + if (narg < iarg+2) + error->fix_error(FLERR,this,"not enough arguments for 'bonded'"); + if(0 == strcmp(arg[iarg+1],"yes")) + bonded = true; + else if(0 == strcmp(arg[iarg+1],"no")) + bonded = false; + else + error->fix_error(FLERR,this,"expecting 'yes' or 'no' after 'bonded'"); + iarg+=2; + } else if(strcmp(style,"particletemplate/multiplespheres") == 0) error->fix_error(FLERR,this,"unknown keyword"); } @@ -223,6 +240,29 @@ void FixTemplateMultiplespheres::post_create() if(0 == strcmp(style,"particletemplate/multiplespheres")) print_info(); + + if(bonded && !fix_bond_random_id) + { + + fix_bond_random_id = static_cast<FixPropertyAtom*>(modify->find_fix_property("bond_random_id","property/atom","scalar",0,0,this->style,false)); + + if(!fix_bond_random_id) + { + const char *fixarg[] = { + "bond_random_id", // fix id + "all", // fix group + "property/atom", // fix style: property/atom + "bond_random_id", // property name + "scalar", // 1 vector per particle + "yes", // restart + "no", // communicate ghost + "no", // communicate rev + "-1." + }; + fix_bond_random_id = modify->add_fix_property_atom(9,const_cast<char**>(fixarg),style); + + } + } } /* ---------------------------------------------------------------------- */ @@ -459,7 +499,7 @@ double FixTemplateMultiplespheres::max_r_bound() double FixTemplateMultiplespheres::min_rad() { - double rmin = 0.; + double rmin = 100000000.; for(int j = 0; j < nspheres; j++) if(rmin > r_sphere[j]) rmin = r_sphere[j]; @@ -560,5 +600,12 @@ void FixTemplateMultiplespheres::randomize_ptilist(int n_random,int distribution pti->groupbit = groupbit | distribution_groupbit; pti_list[i]->distorder = distorder; + + if(bonded) + { + pti_list[i]->fix_property = fix_bond_random_id; + + pti_list[i]->fix_property_value = static_cast<double>(update->ntimestep)+random_insertion->uniform(); + } } } diff --git a/src/fix_template_multiplespheres.h b/src/fix_template_multiplespheres.h index 1100120e1795843c220b166b28f408ffbb1d0994..eb88d1343dd643efebaee61a66b736c819f3d2e2 100644 --- a/src/fix_template_multiplespheres.h +++ b/src/fix_template_multiplespheres.h @@ -66,6 +66,8 @@ class FixTemplateMultiplespheres : public FixTemplateSphere { int maxtype(); int mintype(); int number_spheres(); + bool is_bonded() + { return bonded; } // single insertion virtual void randomize_single(); @@ -127,6 +129,9 @@ class FixTemplateMultiplespheres : public FixTemplateSphere { bool overlap_slightly; bool no_overlap; + + bool bonded; + class FixPropertyAtom *fix_bond_random_id; }; } diff --git a/src/fix_template_multisphere.cpp b/src/fix_template_multisphere.cpp index ff4f5b90a42b29d7e48cabf1fe9b352db897d7e8..8a1fb2d47196b8f755838796e688ce41bdcbc17e 100644 --- a/src/fix_template_multisphere.cpp +++ b/src/fix_template_multisphere.cpp @@ -314,8 +314,8 @@ void FixTemplateMultisphere::init() error->fix_error(FLERR,this,"multisphere template types have to be consecutive starting from 1"); FixMultisphere *fix_multisphere = static_cast<FixMultisphere*>(modify->find_fix_style("multisphere", 0)); - if(fix_multisphere && fix_multisphere->igroup != igroup) - error->fix_error(FLERR,this,"Fix particletemplate/multisphere command and fix multisphere command are not compatible, must be same group"); + if(fix_multisphere && (fix_multisphere->groupbit & groupbit) == 0) + error->fix_error(FLERR,this,"Fix particletemplate/multisphere command and fix multisphere command are not compatible, must be member of the same group"); } /* ---------------------------------------------------------------------- diff --git a/src/fix_template_sphere.cpp b/src/fix_template_sphere.cpp index a70d5b6aa71b70f6abc4b544effdb69b1f2d8e3b..2982a39324bed22b22ca19c81e6b1c3c13a8abaf 100644 --- a/src/fix_template_sphere.cpp +++ b/src/fix_template_sphere.cpp @@ -58,6 +58,7 @@ #include "vector_liggghts.h" #include "mpi_liggghts.h" #include "fix_region_variable.h" +#include "group.h" using namespace LAMMPS_NS; using namespace LMP_PROBABILITY_NS; @@ -272,8 +273,16 @@ FixTemplateSphere::FixTemplateSphere(LAMMPS *lmp, int narg, char **arg) : } else error->fix_error(FLERR,this,"invalid density random style"); - } - else if(strcmp(style,"particletemplate/sphere") == 0) + } else if(strcmp(arg[iarg],"additional_group") == 0) { + if (iarg+2 > narg) + error->fix_error(FLERR,this,"not enough arguments for 'additional_group'"); + iarg++; + const int iAddGroup = group->find(arg[iarg++]); + if (iAddGroup == -1) error->all(FLERR,"Could not find additional fix group ID"); + groupbit = groupbit | group->bitmask[iAddGroup]; + + hasargs = true; + } else if(strcmp(style,"particletemplate/sphere") == 0) error->fix_error(FLERR,this,"unrecognized keyword"); } diff --git a/src/fix_wall_gran.cpp b/src/fix_wall_gran.cpp index 510d6322e25b42412b96d557f02ab97b606850d3..2b33b12aa0c172295766cc782a7a6d6e01278f6c 100644 --- a/src/fix_wall_gran.cpp +++ b/src/fix_wall_gran.cpp @@ -74,7 +74,7 @@ #include "contact_interface.h" #include "fix_property_global.h" #include <vector> -#include "granular_wall.h" + #ifdef SUPERQUADRIC_ACTIVE_FLAG #include "math_extra_liggghts_superquadric.h" #endif @@ -110,7 +110,6 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : stress_flag_ = false; n_FixMesh_ = 0; dnum_ = 0; - skinDistance_ = 0.0; r0_ = 0.; @@ -123,6 +122,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : // initializations fix_wallforce_ = 0; fix_wallforce_contact_ = 0; + fix_meshforce_pbc_ = 0; fix_rigid_ = NULL; heattransfer_flag_ = false; @@ -163,9 +163,13 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : if(!impl && 0 == strncmp(style,"wall/gran",9)) { printf("ERROR: Detected problem with model '%s' (and possibly subsequent arguments). \n", arg[4]); - printf("ERROR: The user must ensure that the contact model for this fix exists in the list of variants. \n"); - printf("ERROR: For the list of variants see the 'style_tangential_model.h' and 'style_normal_model.h' file in the src directory of your LIGGGHTS installation. \n"); - error->fix_error(FLERR,this,"unknown contact model"); + error->fix_error(FLERR,this, "unknown contact model or model not in whitelist. Possible root causes:\n" + " (1) it's a typo. Check the documentation of the contact model you are using.\n" + " (2) the contact model is not available in your installation. Check if a documentation for this.\n" + " contact model is available at all in your version.\n" + " (3) the model is part of a package which was not installed. Check the documentation for details. \n" + " (4) the model is available, but was not in the whitelist during compilation. Check if a file \n" + " src/style_contact_model.whitelist exists. If yes, modify it and re-compile.\n"); } iarg_ = narg - nremaining; @@ -435,6 +439,30 @@ void FixWallGran::post_create() delete []fixarg; delete []hist_name; } + + if((domain->xperiodic || domain->yperiodic || domain->zperiodic) && 1 == meshwall_) + { + char *wallforce_name = new char[strlen(style)+1+15]; + strcpy(wallforce_name,"meshforce_pbc_"); + strcat(wallforce_name,id); + char **fixarg = new char*[11]; + fixarg[0] = wallforce_name; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "property/atom"; + fixarg[3] = wallforce_name; + fixarg[4] = (char *) "vector"; + fixarg[5] = (char *) "no"; // restart + fixarg[6] = (char *) "no"; // communicate ghost + fixarg[7] = (char *) "yes"; // communicate rev + fixarg[8] = (char *) "0."; + fixarg[9] = (char *) "0."; + fixarg[10] = (char *) "0."; + modify->add_fix(11,fixarg); + fix_meshforce_pbc_ = + static_cast<FixPropertyAtom*>(modify->find_fix_property(wallforce_name,"property/atom","vector",3,0,style)); + delete []fixarg; + delete []wallforce_name; + } } /* ---------------------------------------------------------------------- */ @@ -446,6 +474,9 @@ void FixWallGran::pre_delete(bool unfixflag) if(unfixflag && fix_history_primitive_) modify->delete_fix(fix_history_primitive_->id); + if(unfixflag && fix_meshforce_pbc_) + modify->delete_fix(fix_meshforce_pbc_->id); + if(unfixflag && store_force_contact_ && 0 == meshwall_) modify->delete_fix(fix_wallforce_contact_->id); @@ -612,6 +643,7 @@ void FixWallGran::post_force(int vflag) addflag_ = 0; post_force_wall(vflag); + } /* ---------------------------------------------------------------------- @@ -626,6 +658,13 @@ void FixWallGran::post_force_pgl() addflag_ = 1; post_force_wall(0); + + // call finalize for cwl + if(cwl_) + { + + cwl_->pair_finalize(); + } } /* ---------------------------------------------------------------------- @@ -704,13 +743,18 @@ void FixWallGran::post_force_mesh(int vflag) double v_wall[3],bary[3]; double delta[3],deltan; MultiVectorContainer<double,3,3> *vMeshC; - double ***vMesh; + double *radius = atom->radius; + double ***vMesh = 0; int nlocal = atom->nlocal; - int nTriAll; + int nTriAll, barysign = -1; + double OneMinusContactDistanceFactor = 1.-neighbor->contactDistanceFactor; SurfacesIntersectData sidata; sidata.is_wall = true; + if(fix_meshforce_pbc_) + fix_meshforce_pbc_->set_all(0.,true); + for(int iMesh = 0; iMesh < n_FixMesh_; iMesh++) { TriMesh *mesh = FixMesh_list_[iMesh]->triMesh(); @@ -727,19 +771,17 @@ void FixWallGran::post_force_mesh(int vflag) // get neighborList and numNeigh FixNeighlistMesh * meshNeighlist = FixMesh_list_[iMesh]->meshNeighlist(); + // moving mesh vectorZeroize3D(v_wall); vMeshC = mesh->prop().getElementProperty<MultiVectorContainer<double,3,3> >("v"); + if(vMeshC) + vMesh = vMeshC->begin(); atom_type_wall_ = FixMesh_list_[iMesh]->atomTypeWall(); - // moving mesh - if(vMeshC) + // loop owned and ghost triangles + for(int iTri = 0; iTri < nTriAll; iTri++) { - vMesh = vMeshC->begin(); - - // loop owned and ghost triangles - for(int iTri = 0; iTri < nTriAll; iTri++) - { const std::vector<int> & neighborList = meshNeighlist->get_contact_list(iTri); const int numneigh = neighborList.size(); for(int iCont = 0; iCont < numneigh; iCont++) @@ -747,8 +789,9 @@ void FixWallGran::post_force_mesh(int vflag) const int iPart = neighborList[iCont]; - // do not need to handle ghost particles - if(iPart >= nlocal) continue; + // do not handle ghost particles unless periodic + + if((iPart >= nlocal) && (!domain->is_periodic_ghost(iPart))) continue; int idTri = mesh->id(iTri); @@ -767,86 +810,36 @@ void FixWallGran::post_force_mesh(int vflag) } else deltan = mesh->resolveTriSphereContactBary(iPart,iTri,radius_ ? radius_[iPart]:r0_ ,x_[iPart],delta,bary); #else - deltan = mesh->resolveTriSphereContactBary(iPart,iTri,radius_ ? radius_[iPart]:r0_ ,x_[iPart],delta,bary); + deltan = mesh->resolveTriSphereContactBary(iPart,iTri,radius_ ? radius_[iPart]:r0_ ,x_[iPart],delta,bary,barysign); #endif - if(deltan > skinDistance_) //allow force calculation away from the wall - { - - } - else - { - - if(fix_contact && ! fix_contact->handleContact(iPart,idTri,sidata.contact_history)) continue; - - for(int i = 0; i < 3; i++) - v_wall[i] = (bary[0]*vMesh[iTri][0][i] + bary[1]*vMesh[iTri][1][i] + bary[2]*vMesh[iTri][2][i]); - - sidata.i = iPart; - sidata.deltan = -deltan; - sidata.delta[0] = -delta[0]; - sidata.delta[1] = -delta[1]; - sidata.delta[2] = -delta[2]; - post_force_eval_contact(sidata, v_wall,iMesh,FixMesh_list_[iMesh],mesh,iTri); - } - - } - } - } - // non-moving mesh - do not calculate v_wall, use standard distance function - else - { - // loop owned and ghost particles - for(int iTri = 0; iTri < nTriAll; iTri++) - { - const std::vector<int> & neighborList = meshNeighlist->get_contact_list(iTri); - const int numneigh = neighborList.size(); - - for(int iCont = 0; iCont < numneigh; iCont++) - { - const int iPart = neighborList[iCont]; - - // do not need to handle ghost particles - if(iPart >= nlocal) continue; + if(deltan > cutneighmax_) continue; - int idTri = mesh->id(iTri); - #ifdef SUPERQUADRIC_ACTIVE_FLAG - if(atom->superquadric_flag) { - sidata.pos_i = x_[iPart]; - sidata.quat_i = quat_[iPart]; - sidata.shape_i = shape_[iPart]; - sidata.roundness_i = roundness_[iPart]; - Superquadric particle(sidata.pos_i, sidata.quat_i, sidata.shape_i, sidata.roundness_i); - if(mesh->sphereTriangleIntersection(iTri, radius_[iPart], sidata.pos_i)) //check for Bounding Sphere-triangle intersection - deltan = mesh->resolveTriSuperquadricContact(iTri, delta, sidata.contact_point, particle); - else - deltan = LARGE_TRIMESH; - sidata.is_non_spherical = true; //by default it is false - } else - deltan = mesh->resolveTriSphereContact(iPart,iTri,radius_ ? radius_[iPart]:r0_,x_[iPart],delta); - #else - deltan = mesh->resolveTriSphereContact(iPart,iTri,radius_ ? radius_[iPart]:r0_,x_[iPart],delta); - #endif - - if(deltan > skinDistance_) //allow force calculation away from the wall - { - - } - - else + if(deltan <= 0 || (radius && deltan < OneMinusContactDistanceFactor*radius[iPart])) { - if(fix_contact && ! fix_contact->handleContact(iPart,idTri,sidata.contact_history)) continue; - + bool intersectflag = (deltan <= 0); + if(fix_contact && ! fix_contact->handleContact(iPart,idTri,sidata.contact_history,intersectflag,7 == barysign)) continue; + + if(vMeshC) + { + for(int i = 0; i < 3; i++) + v_wall[i] = (bary[0]*vMesh[iTri][0][i] + bary[1]*vMesh[iTri][1][i] + bary[2]*vMesh[iTri][2][i]); + } sidata.i = iPart; - sidata.deltan = -deltan; + sidata.deltan = -deltan; sidata.delta[0] = -delta[0]; sidata.delta[1] = -delta[1]; sidata.delta[2] = -delta[2]; - post_force_eval_contact(sidata, v_wall,iMesh,FixMesh_list_[iMesh],mesh,iTri); + if(impl) + impl->compute_force(this, sidata, intersectflag,v_wall,FixMesh_list_[iMesh],iMesh,mesh,iTri); + else + { + sidata.r = r0_ - sidata.deltan; + compute_force(sidata, v_wall); // LEGACY CODE (SPH) + } } } - } } // clean-up contacts @@ -854,6 +847,14 @@ void FixWallGran::post_force_mesh(int vflag) if(fix_contact) fix_contact->cleanUpContacts(); } + if(fix_meshforce_pbc_) + { + fix_meshforce_pbc_->do_reverse_comm(); + double **f = atom->f; + + for(int i = 0; i < nlocal; i++) + vectorAdd3D(f[i],fix_meshforce_pbc_->array_atom[i],f[i]); + } } /* ---------------------------------------------------------------------- @@ -866,7 +867,9 @@ void FixWallGran::post_force_primitive(int vflag) SurfacesIntersectData sidata; sidata.is_wall = true; - + double *radius = atom->radius; + double OneMinusContactDistanceFactor = 1.-neighbor->contactDistanceFactor; + // contact properties double delta[3]={},deltan,rdist[3]; double v_wall[] = {0.,0.,0.}; @@ -890,15 +893,15 @@ void FixWallGran::post_force_primitive(int vflag) deltan = primitiveWall_->resolveContact(x_[iPart],radius_?radius_[iPart]:r0_,delta); - if(deltan > skinDistance_) //allow force calculation away from the wall - { - if(c_history) vectorZeroizeN(c_history[iPart],dnum_); - } - else + if(deltan>cutneighmax_) continue; + + if(deltan <= 0 || deltan < OneMinusContactDistanceFactor*radius[iPart]) { - bool particle_wall_intersection = true; //always true for spheres + // spheres + bool intersectflag = (deltan <= 0); + #ifdef SUPERQUADRIC_ACTIVE_FLAG - if(atom->superquadric_flag) { + if(atom->superquadric_flag) { double sphere_contact_point[3]; vectorAdd3D(x_[iPart], delta, sphere_contact_point); sidata.pos_i = x_[iPart]; @@ -907,102 +910,52 @@ void FixWallGran::post_force_primitive(int vflag) sidata.roundness_i = roundness_[iPart]; double closestPoint[3], closestPointProjection[3], point_of_lowest_potential[3]; Superquadric particle(sidata.pos_i, sidata.quat_i, sidata.shape_i, sidata.roundness_i); - particle_wall_intersection = particle.plane_intersection(delta, sphere_contact_point, closestPoint, point_of_lowest_potential); + intersectflag = particle.plane_intersection(delta, sphere_contact_point, closestPoint, point_of_lowest_potential); deltan = -MathExtraLiggghtsSuperquadric::point_wall_projection(delta, sphere_contact_point, closestPoint, closestPointProjection); vectorCopy3D(closestPoint, sidata.contact_point); sidata.is_non_spherical = true; //by default it is false - } + } #endif - if(particle_wall_intersection) { //always true for spheres - if(shear_ && shearAxis_ >= 0) - { - primitiveWall_->calcRadialDistance(x_[iPart],rdist); - vectorCross3D(shearAxisVec_,rdist,v_wall); - - } - sidata.i = iPart; - sidata.contact_history = c_history ? c_history[iPart] : NULL; - sidata.deltan = -deltan; - sidata.delta[0] = -delta[0]; - sidata.delta[1] = -delta[1]; - sidata.delta[2] = -delta[2]; - post_force_eval_contact(sidata,v_wall); - } else { - if(c_history) vectorZeroizeN(c_history[iPart],dnum_); + + if(shear_ && shearAxis_ >= 0) + { + primitiveWall_->calcRadialDistance(x_[iPart],rdist); + vectorCross3D(shearAxisVec_,rdist,v_wall); + + } + sidata.i = iPart; + sidata.contact_history = c_history ? c_history[iPart] : NULL; + sidata.deltan = -deltan; + sidata.delta[0] = -delta[0]; + sidata.delta[1] = -delta[1]; + sidata.delta[2] = -delta[2]; + + if(impl) + impl->compute_force(this, sidata, intersectflag,v_wall); + else + { + sidata.r = r0_ - sidata.deltan; + compute_force(sidata, v_wall); // LEGACY CODE (SPH) + } + } + + else + { + if(c_history) + { + vectorZeroizeN(c_history[iPart],dnum_); } } } } +/* ---------------------------------------------------------------------- */ + void FixWallGran::compute_force(SurfacesIntersectData &, double *) { } -/* ---------------------------------------------------------------------- - actually calculate force, called for both mesh and primitive -------------------------------------------------------------------------- */ - -inline void FixWallGran::post_force_eval_contact(SurfacesIntersectData & sidata, double * v_wall, int iMesh, FixMeshSurface *fix_mesh, TriMesh *mesh, int iTri) -{ - const int iPart = sidata.i; - - // deltan > 0 in compute_force - // but negative in distance algorithm - sidata.r = (radius_ ? radius_[iPart] : r0_) - sidata.deltan; // sign of corrected, because negative value is passed - sidata.rsq = sidata.r*sidata.r; - sidata.meff = rmass_ ? rmass_[iPart] : atom->mass[atom->type[iPart]]; - sidata.area_ratio = 1.; - - sidata.computeflag = computeflag_; - sidata.shearupdate = shearupdate_; - sidata.jtype = atom_type_wall_; - - double force_old[3]={}, f_pw[3]; - - // if force should be stored - remember old force - if(store_force_ || stress_flag_) - vectorCopy3D(f_[iPart],force_old); - - // add to cwl - if(cwl_ && addflag_) - { - double contactPoint[3]; - vectorSubtract3D(x_[sidata.i],sidata.delta,contactPoint); - cwl_->add_wall_1(iMesh,mesh->id(iTri),iPart,contactPoint,v_wall); - } - - if(impl) - impl->compute_force(this, sidata, v_wall,mesh,iTri); - else - compute_force(sidata, v_wall); // LEGACY CODE (SPH) - - // if force should be stored or evaluated - if(store_force_ || stress_flag_) - { - vectorSubtract3D(f_[iPart],force_old,f_pw); - - if(store_force_) - vectorAdd3D (wallforce_[iPart], f_pw, wallforce_[iPart]); - - if(stress_flag_ && fix_mesh->trackStress()) - { - double delta[3]; - delta[0] = -sidata.delta[0]; - delta[1] = -sidata.delta[1]; - delta[2] = -sidata.delta[2]; - static_cast<FixMeshSurfaceStress*>(fix_mesh)->add_particle_contribution - ( - iPart,f_pw,delta,iTri,v_wall - ); - } - } - - // add heat flux - if(heattransfer_flag_) - addHeatFlux(mesh,iPart,sidata.deltan,1.); -} - /* ---------------------------------------------------------------------- */ int FixWallGran::is_moving() diff --git a/src/fix_wall_gran.h b/src/fix_wall_gran.h index 765a5917d8db848d657740bc090ed3dc859fdffe..fd31a38f1d47d021d667a0260636ce2b6c0ced2b 100644 --- a/src/fix_wall_gran.h +++ b/src/fix_wall_gran.h @@ -61,6 +61,9 @@ namespace LCM = LIGGGHTS::ContactModels; namespace LAMMPS_NS { class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { + + friend class LIGGGHTS::Walls::IGranularWall; + public: FixWallGran(class LAMMPS *, int, char **); ~FixWallGran(); @@ -81,72 +84,70 @@ class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { /* PUBLIC ACCESS FUNCTIONS */ - void setSkinDistance(double newSkinDistance) - { skinDistance_ = newSkinDistance; } - void setDnum(int newDnum) { dnum_ = newDnum; } - inline int store_force() + inline int store_force() const { return store_force_; } - inline int iarg() + inline FixPropertyAtom* fix_meshforce_pbc() const + { return fix_meshforce_pbc_; } + + inline FixPropertyAtom* fix_wallforce() const + { return fix_wallforce_; } + + inline int iarg() const { return iarg_; } - int add_history_value(std::string name, std::string newtonflag) { - return dnum_++; - } + int add_history_value(std::string name, std::string newtonflag) + { return dnum_++; } - inline int dnum() + inline int dnum() const { return dnum_; } - inline int n_meshes() + inline int n_meshes() const { return n_FixMesh_; } - inline class FixMeshSurface ** mesh_list() + inline class FixMeshSurface ** mesh_list() const { return FixMesh_list_; } - inline int atom_type_wall() + inline int atom_type_wall() const { return atom_type_wall_; } - inline bool is_mesh_wall() + inline bool is_mesh_wall() const { return 1 == meshwall_; } - inline bool store_force_contact() - { return store_force_contact_; } + inline int computeflag() const + { return computeflag_; } - class PrimitiveWall* primitiveWall(); + inline int shearupdate() const + { return shearupdate_; } - int n_contacts_all(); - int n_contacts_all(int); - int n_contacts_local(); - int n_contacts_local(int); - int is_moving(); + inline int heattransfer_flag() const + { return heattransfer_flag_; } - void register_compute_wall_local(ComputePairGranLocal *,int&); - void unregister_compute_wall_local(ComputePairGranLocal *ptr); + inline int stress_flag() const + { return stress_flag_; } - ComputePairGranLocal * compute_pair_gran_local() { - return cwl_; - } + inline bool store_force_contact() const + { return store_force_contact_; } - int addflag() const { - return addflag_; - } + inline ComputePairGranLocal * compute_wall_gran_local() const + { return cwl_; } - int body(int i) { - return body_[i]; - } + inline int addflag() const + { return addflag_; } - double masstotal(int i) { - return masstotal_[i]; - } + inline int body(int i) const + { return body_[i]; } - class FixRigid *fix_rigid() { - return fix_rigid_; - } + inline double masstotal(int i) const + { return masstotal_[i]; } + + inline class FixRigid *fix_rigid() const + { return fix_rigid_; } - void add_contactforce_wall(int ip, const LCM::ForceData & i_forces,int idTri) + inline void add_contactforce_wall(int ip, const LCM::ForceData & i_forces,int idTri) { // add to fix wallforce contact // adds 0 as ID for primitive wall @@ -160,16 +161,18 @@ class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { } } - void cwl_add_wall_2(const LCM::SurfacesIntersectData & sidata, const LCM::ForceData & i_forces) - { - const double fx = i_forces.delta_F[0]; - const double fy = i_forces.delta_F[1]; - const double fz = i_forces.delta_F[2]; - const double tor1 = i_forces.delta_torque[0]*sidata.area_ratio; - const double tor2 = i_forces.delta_torque[1]*sidata.area_ratio; - const double tor3 = i_forces.delta_torque[2]*sidata.area_ratio; - cwl_->add_wall_2(sidata.i,fx,fy,fz,tor1,tor2,tor3,sidata.contact_history,sidata.rsq); - } + class PrimitiveWall* primitiveWall(); + + int n_contacts_all(); + int n_contacts_all(int); + int n_contacts_local(); + int n_contacts_local(int); + int is_moving(); + + void register_compute_wall_local(ComputePairGranLocal *,int&); + void unregister_compute_wall_local(ComputePairGranLocal *ptr); + + void addHeatFlux(class TriMesh *mesh,int i,double rsq,double area_ratio); protected: @@ -210,7 +213,6 @@ class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { // virtual functions that allow implementation of the // actual physics in the derived classes virtual void compute_force(LCM::SurfacesIntersectData & sidata, double *vwall); - void addHeatFlux(class TriMesh *mesh,int i,double rsq,double area_ratio); // sets flag that neigh list shall be built virtual void pre_neighbor(); @@ -250,7 +252,7 @@ class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { // distance in order to calculate interaction with // rough wall - double skinDistance_; + //double skinDistance_; // number of values for contact history int dnum_; @@ -275,12 +277,12 @@ class FixWallGran : public Fix, public LIGGGHTS::IContactHistorySetup { bool store_force_; class FixPropertyAtom *fix_wallforce_; + class FixPropertyAtom *fix_meshforce_pbc_; + // max neigh cutoff - as in Neighbor double cutneighmax_; virtual void post_force_wall(int vflag); - - inline void post_force_eval_contact(LCM::SurfacesIntersectData & sidata, double * v_wall, int iMesh = -1, FixMeshSurface *fix_mesh = 0, TriMesh *mesh = 0, int iTri = 0); }; } diff --git a/src/fix_wall_gran_base.h b/src/fix_wall_gran_base.h index e1aca0b670308f84b0846c25c0eab2654318676a..5321079cce44fe9dea7c8ff2a1cc9935b5242ca6 100644 --- a/src/fix_wall_gran_base.h +++ b/src/fix_wall_gran_base.h @@ -48,6 +48,7 @@ #include "fix_contact_property_atom_wall.h" #include "contact_interface.h" #include "compute_pair_gran_local.h" +#include "fix_mesh_surface_stress.h" #include "tri_mesh.h" #include "settings.h" #include "string.h" @@ -77,7 +78,8 @@ public: { } - virtual ~Granular() { + virtual ~Granular() + { } virtual void init_granular() { @@ -127,10 +129,11 @@ public: } } - virtual void compute_force(FixWallGran * wg, SurfacesIntersectData & sidata, double *vwall, class TriMesh *mesh = 0,int iTri = 0) + virtual void compute_force(FixWallGran * wg, SurfacesIntersectData & sidata, bool intersectflag,double *vwall, class FixMeshSurface * fix_mesh = 0, int iMesh = 0, class TriMesh *mesh = 0,int iTri = 0) { const int ip = sidata.i; + double *x = atom->x[ip]; double *f = atom->f[ip]; double *torque = atom->torque[ip]; double *v = atom->v[ip]; @@ -139,11 +142,48 @@ public: double mass = atom->rmass[ip]; int *type = atom->type; + // copy collision data to struct (compiler can figure out a better way to + // interleave these stores with the double calculations above. + ForceData i_forces; + ForceData j_forces; + sidata.v_i = v; + sidata.v_j = vwall; + sidata.omega_i = omega; + + sidata.r = radius - sidata.deltan; // sign corrected, because negative value is passed + sidata.rsq = sidata.r*sidata.r; + const double rinv = 1.0/sidata.r; + sidata.rinv = rinv; + sidata.area_ratio = 1.; + + //store type here as negative in case of primitive wall! + sidata.j = mesh ? iTri : -wg->atom_type_wall(); + sidata.contact_flags = NULL; + sidata.itype = type[ip]; + if(wg->fix_rigid() && wg->body(ip) >= 0) mass = wg->masstotal(wg->body(ip)); - const double r = sidata.r; - const double rinv = 1.0/r; + sidata.meff = mass; + sidata.mi = mass; + + sidata.computeflag = wg->computeflag(); + sidata.shearupdate = wg->shearupdate(); + sidata.jtype = wg->atom_type_wall(); + + double force_old[3]={}, f_pw[3]; + + // if force should be stored - remember old force + if(wg->store_force() || wg->stress_flag() || wg->fix_meshforce_pbc()) + vectorCopy3D(f,force_old); + + // add to cwl + if(wg->compute_wall_gran_local() && wg->addflag()) + { + double contactPoint[3]; + vectorSubtract3D(x,sidata.delta,contactPoint); + wg->compute_wall_gran_local()->add_wall_1(iMesh,mesh->id(iTri),ip,contactPoint,vwall); + } #ifdef SUPERQUADRIC_ACTIVE_FLAG double enx, eny, enz; @@ -168,41 +208,72 @@ public: const double enz = sidata.delta[2] * rinv; sidata.radi = radius; #endif - - // copy collision data to struct (compiler can figure out a better way to - // interleave these stores with the double calculations above. - ForceData i_forces; - ForceData j_forces; - sidata.v_i = v; - sidata.v_j = vwall; - sidata.omega_i = omega; + sidata.radsum = radius; sidata.en[0] = enx; sidata.en[1] = eny; sidata.en[2] = enz; - sidata.i = ip; - sidata.j = mesh?iTri : -1; - sidata.contact_flags = NULL; - sidata.itype = type[ip]; - - sidata.r = r; - sidata.rinv = rinv; - sidata.radsum = radius; - sidata.mi = mass; - cmodel.surfacesIntersect(sidata, i_forces, j_forces); - - cmodel.endSurfacesIntersect(sidata,mesh); + if (intersectflag) + { + cmodel.surfacesIntersect(sidata, i_forces, j_forces); + cmodel.endSurfacesIntersect(sidata,mesh); + // if there is a surface touch, there will always be a force + sidata.has_force_update = true; + } + else + { + // apply force update only if selected contact models have requested it + sidata.has_force_update = false; + cmodel.surfacesClose(sidata, i_forces, j_forces); + } - if(sidata.computeflag) { + if(sidata.computeflag && sidata.has_force_update) { force_update(f, torque, i_forces); } - if (wg->store_force_contact()) { + if (wg->store_force_contact() && (intersectflag)) + { wg->add_contactforce_wall(ip,i_forces,mesh?mesh->id(iTri):0); } - if(wg->compute_pair_gran_local() && wg->addflag()) { - wg->cwl_add_wall_2(sidata, i_forces); + if(wg->compute_wall_gran_local() && wg->addflag() && (intersectflag)) + { + const double fx = i_forces.delta_F[0]; + const double fy = i_forces.delta_F[1]; + const double fz = i_forces.delta_F[2]; + const double tor1 = i_forces.delta_torque[0]*sidata.area_ratio; + const double tor2 = i_forces.delta_torque[1]*sidata.area_ratio; + const double tor3 = i_forces.delta_torque[2]*sidata.area_ratio; + wg->compute_wall_gran_local()->add_wall_2(sidata.i,fx,fy,fz,tor1,tor2,tor3,sidata.contact_history,sidata.rsq); + } + + // add heat flux + + if(intersectflag && wg->heattransfer_flag()) + wg->addHeatFlux(mesh,ip,sidata.deltan,1.); + + // if force should be stored or evaluated + if((sidata.has_force_update) && (wg->store_force() || wg->stress_flag() || wg->fix_meshforce_pbc())) + { + vectorSubtract3D(f,force_old,f_pw); + + if(wg->store_force()) + vectorAdd3D (wg->fix_wallforce()->array_atom[ip], f_pw, wg->fix_wallforce()->array_atom[ip]); + + if(wg->fix_meshforce_pbc() && ip >= atom->nlocal) + vectorAdd3D (wg->fix_meshforce_pbc()->array_atom[ip], f_pw, wg->fix_meshforce_pbc()->array_atom[ip]); + + if(wg->stress_flag() && fix_mesh->trackStress()) + { + double delta[3]; + delta[0] = -sidata.delta[0]; + delta[1] = -sidata.delta[1]; + delta[2] = -sidata.delta[2]; + static_cast<FixMeshSurfaceStress*>(fix_mesh)->add_particle_contribution + ( + ip,f_pw,delta,iTri,vwall + ); + } } } }; diff --git a/src/general_container.h b/src/general_container.h index fef113c28899ea9817d710071b71e959161f0974..daaed3fb4e2d405331bbbdea27aaae348d82155d 100644 --- a/src/general_container.h +++ b/src/general_container.h @@ -48,8 +48,10 @@ #include "memory_ns.h" #include "math_extra_liggghts.h" #include <string.h> +#include <limits> -#define GROW 100 +inline int GROW_CONTAINER() +{ return 10000; } using namespace LAMMPS_MEMORY_NS; @@ -64,6 +66,9 @@ namespace LAMMPS_NS bool isDoubleData(); bool isIntData(); + bool subtract (GeneralContainer<T,NUM_VEC,LEN_VEC> const &A, + GeneralContainer<T,NUM_VEC,LEN_VEC> const &minusB); + void add(T** elem); void addZero(); @@ -87,8 +92,10 @@ namespace LAMMPS_NS bool setFromContainer(ContainerBase *cont); - bool calcAveFromContainer(double weighting_factor); - bool calcVarFromContainer(double weighting_factor); + bool calcAvgFromContainer(); + bool calcMeanSquareFromContainer(); + bool calcSumFromContainer(); + bool normalizeContainer(); T max_scalar(); T min_scalar(); diff --git a/src/general_container_I.h b/src/general_container_I.h index 5937c977c5452b7430590cb6bbbbb6a9feb82241..8d9feda4b9a8487fe91d1f84e1191085b6936728 100644 --- a/src/general_container_I.h +++ b/src/general_container_I.h @@ -52,20 +52,20 @@ GeneralContainer<T,NUM_VEC,LEN_VEC>::GeneralContainer(const char *_id) : ContainerBase(_id), numElem_(0), - maxElem_(GROW), + maxElem_(GROW_CONTAINER()), defaultValue_(0) { - create<T>(arr_,GROW,NUM_VEC,LEN_VEC); + create<T>(arr_,GROW_CONTAINER(),NUM_VEC,LEN_VEC); } template<typename T, int NUM_VEC, int LEN_VEC> GeneralContainer<T,NUM_VEC,LEN_VEC>::GeneralContainer(const char *_id, const char *_comm, const char *_ref, const char *_restart, int _scalePower) : ContainerBase(_id, _comm, _ref, _restart, _scalePower), numElem_(0), - maxElem_(GROW), + maxElem_(GROW_CONTAINER()), defaultValue_(0) { - create<T>(arr_,GROW,NUM_VEC,LEN_VEC); + create<T>(arr_,GROW_CONTAINER(),NUM_VEC,LEN_VEC); } template<typename T, int NUM_VEC, int LEN_VEC> @@ -126,13 +126,39 @@ add element(s) ------------------------------------------------------------------------- */ + template<typename T, int NUM_VEC, int LEN_VEC> + bool GeneralContainer<T,NUM_VEC,LEN_VEC>::subtract(GeneralContainer<T,NUM_VEC,LEN_VEC> const &A, + GeneralContainer<T,NUM_VEC,LEN_VEC> const &minusB) + { + int len = size(); + int lenA = A.size(); + int lenB = minusB.size(); + + if(lenA != lenB) + return false; + + if(len < lenA) + addUninitialized(lenA-len); + + for(int i = 0; i < len; i++) + for(int j = 0; j < NUM_VEC; j++) + for(int k = 0; k < LEN_VEC; k++) + arr_[i][j][k] = A(i)[j][k] - minusB(i)[j][k]; + + return true; + } + + /* ---------------------------------------------------------------------- + add element(s) + ------------------------------------------------------------------------- */ + template<typename T, int NUM_VEC, int LEN_VEC> void GeneralContainer<T,NUM_VEC,LEN_VEC>::add(T** elem) { if(numElem_ == maxElem_) { - grow<T>(arr_,maxElem_+GROW,NUM_VEC,LEN_VEC); - maxElem_ += GROW; + grow<T>(arr_,maxElem_+GROW_CONTAINER(),NUM_VEC,LEN_VEC); + maxElem_ += GROW_CONTAINER(); } for(int i=0;i<NUM_VEC;i++) for(int j=0;j<LEN_VEC;j++) @@ -145,8 +171,8 @@ { if(numElem_ == maxElem_) { - grow<T>(arr_,maxElem_+GROW,NUM_VEC,LEN_VEC); - maxElem_ += GROW; + grow<T>(arr_,maxElem_+GROW_CONTAINER(),NUM_VEC,LEN_VEC); + maxElem_ += GROW_CONTAINER(); } for(int i=0;i<NUM_VEC;i++) for(int j=0;j<LEN_VEC;j++) @@ -161,12 +187,12 @@ if(numElem_ >= maxElem_) { T init_val = static_cast<T>(0); - grow(arr_,numElem_+GROW,NUM_VEC,LEN_VEC); - for(int i = numElem_; i < numElem_+GROW; i++) + grow(arr_,numElem_+GROW_CONTAINER(),NUM_VEC,LEN_VEC); + for(int i = numElem_; i < numElem_+GROW_CONTAINER(); i++) for(int j=0;j<NUM_VEC;j++) for(int k=0;k<LEN_VEC;k++) arr_[i][j][k] = init_val; - maxElem_ = numElem_ + GROW; + maxElem_ = numElem_ + GROW_CONTAINER(); } } @@ -322,47 +348,188 @@ ------------------------------------------------------------------------- */ template<typename T, int NUM_VEC, int LEN_VEC> - bool GeneralContainer<T,NUM_VEC,LEN_VEC>::calcAveFromContainer(double weighting_factor) + bool GeneralContainer<T,NUM_VEC,LEN_VEC>::calcAvgFromContainer() { + GeneralContainer<T,NUM_VEC,LEN_VEC> *gcont = static_cast<GeneralContainer<T,NUM_VEC,LEN_VEC>* >(container_statistics_raw_data_); + GeneralContainer<T,1,1> *gscale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_scale_data_); + GeneralContainer<T,1,1> *gRedScale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_reduced_scale_data_); + // source has to be defined + if (!gcont) + return false; + + // only use if identical dimensions if(size() != gcont->size() || nVec() != gcont->nVec() || lenVec() != gcont->lenVec()) return false; - int len = size(); - for(int n = 0; n < len; n++) - for(int i=0;i<NUM_VEC;i++) + const int len = size(); + + if (!gscale || !gRedScale) + { + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) for(int j=0;j<LEN_VEC;j++) - { - arr_[n][i][j] = (1.-weighting_factor)*arr_[n][i][j]+weighting_factor*gcont->arr_[n][i][j]; - - } + if(averaging_forget_ || (*gcont)(n)[i][j] != 0 ) + arr_[n][i][j] = (1.-weighting_factor_)*arr_[n][i][j]+weighting_factor_*(*gcont)(n)[i][j]; + } + else + { + if(size() != gscale->size() || size() != gRedScale->size()) + return false; + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + arr_[n][i][j] = (1.-weighting_factor_)*(1.-weighting_factor_)*arr_[n][i][j]*(*gRedScale)(n)[1][1]+(*gcont)(n)[i][j]*(*gscale)(n)[1][1]; + } return true; } /* ---------------------------------------------------------------------- - variance from other container + mean square from other container ------------------------------------------------------------------------- */ template<typename T, int NUM_VEC, int LEN_VEC> - bool GeneralContainer<T,NUM_VEC,LEN_VEC>::calcVarFromContainer(double weighting_factor) + bool GeneralContainer<T,NUM_VEC,LEN_VEC>::calcMeanSquareFromContainer() { + GeneralContainer<T,NUM_VEC,LEN_VEC> *gcont = static_cast<GeneralContainer<T,NUM_VEC,LEN_VEC>* >(container_statistics_raw_data_); + GeneralContainer<T,1,1> *gscale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_scale_data_); + GeneralContainer<T,1,1> *gRedScale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_reduced_scale_data_); + + // at least source has to be defined + if (!gcont) + return false; + // only copy if identical if(size() != gcont->size() || nVec() != gcont->nVec() || lenVec() != gcont->lenVec()) return false; - int len = size(); - for(int n = 0; n < len; n++) - for(int i=0;i<NUM_VEC;i++) + const int len = size(); + + if (!gscale || !gRedScale) + { + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) for(int j=0;j<LEN_VEC;j++) { - // TODO HERE this is ave - arr_[n][i][j] = (1.-weighting_factor)*arr_[n][i][j]+weighting_factor*gcont->arr_[n][i][j]; - //arr_[n][i][j] = (1.-weighting_factor)*arr_[n][i][j]+weighting_factor*gcont->arr_[n][i][j]; - + const T contribution = gcont->arr_[n][i][j]; + if(averaging_forget_ || contribution != 0) + arr_[n][i][j] = (1.-weighting_factor_)*arr_[n][i][j]+weighting_factor_*contribution*contribution; + + } + } + else + { + if(size() != gscale->size() || size() != gRedScale->size()) + return false; + + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + { + const T contribution = gcont->arr_[n][i][j]; + const T scale = (*gscale)(n)[i][j]; + const T redScale = (*gRedScale)(n)[i][j]; + arr_[n][i][j] = (1.-weighting_factor_)*(1.-weighting_factor_)*arr_[n][i][j]*redScale+scale*contribution*contribution; + } + } + + return true; + } + + template<typename T, int NUM_VEC, int LEN_VEC> + bool GeneralContainer<T,NUM_VEC,LEN_VEC>::normalizeContainer() + { + + GeneralContainer<T,NUM_VEC,LEN_VEC> *gcont = static_cast<GeneralContainer<T,NUM_VEC,LEN_VEC>* >(container_statistics_raw_data_); + GeneralContainer<T,1,1> *gscale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_scale_data_); + GeneralContainer<T,1,1> *gRedScale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_reduced_scale_data_); + + // at least source has to be defined + if (!gcont) + return false; + + // only copy if identical + if(size() != gcont->size() || nVec() != gcont->nVec() || lenVec() != gcont->lenVec()) + return false; + + const int len = size(); + if (!gscale || !gRedScale) + return true; + else + { + if(size() != gscale->size() || size() != gRedScale->size()) + return false; + + for(int n = 0; n < len; n++) + { + if ((*gRedScale)(n)[1][1] < std::numeric_limits<T>::epsilon()) + { + (*gRedScale)(n)[1][1] = 0; + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + arr_[n][i][j] = 0; // assumes weighting factor > 0 + continue; + } + else + { + const T redScaleInv = 1./(*gRedScale)(n)[1][1]; + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + arr_[n][i][j] = arr_[n][i][j]*redScaleInv; + } + } + } + + return true; + } + + template<typename T, int NUM_VEC, int LEN_VEC> + bool GeneralContainer<T,NUM_VEC,LEN_VEC>::calcSumFromContainer() + { + + GeneralContainer<T,NUM_VEC,LEN_VEC> *gcont = static_cast<GeneralContainer<T,NUM_VEC,LEN_VEC>* >(container_statistics_raw_data_); + GeneralContainer<T,1,1> *gscale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_scale_data_); + GeneralContainer<T,1,1> *gRedScale = dynamic_cast<GeneralContainer<T,1,1>* >(container_statistics_reduced_scale_data_); + + // at least source has to be defined + if (!gcont) + return false; + + // only copy if identical + if(size() != gcont->size() || nVec() != gcont->nVec() || lenVec() != gcont->lenVec()) + return false; + + const int len = size(); + if (!gscale || !gRedScale) + { + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + { + arr_[n][i][j] = (1.-weighting_factor_)*arr_[n][i][j]+(*gcont)(n)[i][j]; + + if (arr_[n][i][j] < std::numeric_limits<T>::epsilon()) + arr_[n][i][j] = 0; } + } + else + { + if(size() != gscale->size() || size() != gRedScale->size()) + return false; + + for(int n = 0; n < len; n++) + for(int i=0;i<NUM_VEC;i++) + for(int j=0;j<LEN_VEC;j++) + { + arr_[n][i][j] = (1.-weighting_factor_)*(1.-weighting_factor_)*arr_[n][i][j]*(*gRedScale)(n)[1][1]+(*gcont)(n)[i][j]*(*gscale)(n)[1][1]; + + if (arr_[n][i][j] < std::numeric_limits<T>::epsilon()) + arr_[n][i][j] = 0; + } + } return true; } diff --git a/src/global_properties.cpp b/src/global_properties.cpp index ae1f554336f4e7e38c22cce564f1922b7416d7e2..dfe41281dfdc2ed109b665ce911dd1685a07e897 100644 --- a/src/global_properties.cpp +++ b/src/global_properties.cpp @@ -46,15 +46,20 @@ #include <cstring> #include <algorithm> #include "update.h" +#include "atom.h" #include "error.h" #include "neighbor.h" +#include "modify.h" #include "force.h" using namespace std; namespace MODEL_PARAMS { + static const char * COALESCENCE_MODEL_SWITCHES = "coalescenceModelSwitches"; + static const char * COALESCENCE_MODEL_SETTINGS = "coalescenceModelSettings"; static const char * COHESION_DISTANCE_SETTINGS = "cohesionDistanceSettings"; + static const char * COHESION_MODEL_SWITCHES = "cohesionModelSwitches"; static const char * COHESION_ENERGY_DENSITY = "cohesionEnergyDensity"; static const char * CHARACTERISTIC_VELOCITY = "characteristicVelocity"; static const char * YOUNGS_MODULUS = "youngsModulus"; @@ -68,6 +73,7 @@ namespace MODEL_PARAMS static const char * MAXIMUM_RESTITUTION = "MaximumRestitution"; static const char * CRITITCAL_STOKES = "CriticalStokes"; static const char * LIQUID_VOLUME = "liquidVolume"; + static const char * LIQUID_DENSITY = "liquidDensity"; static const char * HISTORY_INDEX = "historyIndex"; static const char * SURFACE_TENSION = "surfaceTension"; static const char * SWITCH_MODEL = "switchModel"; @@ -216,6 +222,53 @@ namespace MODEL_PARAMS return charVelScalar; } + /* ---------------------------------------------------------------------- */ + VectorProperty* createCoalescenceModelSwitches(PropertyRegistry & registry, const char * caller, bool sanity_checks) + { + LAMMPS * lmp = registry.getLAMMPS(); + int numSettings = 3; //use 2 settings, index = 0: for bubble-bubble, index = 1: for bubble-wall, 2: decideMethod + VectorProperty * vec = new VectorProperty(numSettings); + FixPropertyGlobal * ca = registry.getGlobalProperty(COALESCENCE_MODEL_SWITCHES,"property/global","vector",numSettings,0,caller); + + for(int i=0; i <numSettings; i++) + { + const double aSetting = ca->compute_vector(i); + + // error checks on v + if(sanity_checks) + { + if(aSetting < 0.0) + lmp->error->all(FLERR,"model switches for coalescence model must be all positive"); + } + vec->data[i] = aSetting; + } + + return vec; + } + /* ---------------------------------------------------------------------- */ + VectorProperty* createCoalescenceModelSettings(PropertyRegistry & registry, const char * caller, bool sanity_checks) + { + LAMMPS * lmp = registry.getLAMMPS(); + int numSettings = 6; //use 6 settings, starting index = 0 + VectorProperty * vec = new VectorProperty(numSettings); + FixPropertyGlobal * ca = registry.getGlobalProperty(COALESCENCE_MODEL_SETTINGS,"property/global","vector",numSettings,0,caller); + + for(int i=0; i <numSettings; i++) + { + const double aSetting = ca->compute_vector(i); + + // error checks on v + if(sanity_checks) + { + if(aSetting < 0.0) + lmp->error->all(FLERR,"model settings for coalescence model must be all positive"); + } + + vec->data[i] = aSetting; + } + + return vec; + } /* ---------------------------------------------------------------------- */ MatrixProperty* createCohesionEnergyDensity(PropertyRegistry & registry, const char * caller, bool sanity_checks) @@ -229,7 +282,7 @@ namespace MODEL_PARAMS { LAMMPS * lmp = registry.getLAMMPS(); int numSettings = 4; //use 4 settings, starting index = 0 - VectorProperty * vec = new VectorProperty(numSettings); + VectorProperty * vec = new VectorProperty(numSettings); FixPropertyGlobal * ca = registry.getGlobalProperty(COHESION_DISTANCE_SETTINGS,"property/global","vector",numSettings,0,caller); for(int i=0; i <numSettings; i++) @@ -251,6 +304,29 @@ namespace MODEL_PARAMS /* ---------------------------------------------------------------------- */ + VectorProperty * createCohesionModelSwitches(PropertyRegistry & registry, const char * caller, bool sanity_checks) + { + LAMMPS * lmp = registry.getLAMMPS(); + int numSettings = 2; //use 2 settings, index = 0: for particle-particle, index = 1: for particle-wall + VectorProperty * vec = new VectorProperty(numSettings); + FixPropertyGlobal * ca = registry.getGlobalProperty(COHESION_MODEL_SWITCHES,"property/global","vector",numSettings,0,caller); + + for(int i=0; i <numSettings; i++) + { + const double aSetting = ca->compute_vector(i); + + // error checks on v + if(sanity_checks) + { + if(aSetting < 0.0) + lmp->error->all(FLERR,"model switches for cohesion model must be all positive"); + } + vec->data[i] = aSetting; + } + + return vec; + } + /* ---------------------------------------------------------------------- */ VectorProperty * createYoungsModulus(PropertyRegistry & registry, const char * caller, bool sanity_checks) { LAMMPS * lmp = registry.getLAMMPS(); @@ -264,7 +340,8 @@ namespace MODEL_PARAMS const double Yi = Y->compute_vector(i-1); // error checks on Y - if(sanity_checks) + + if(sanity_checks && (0 == lmp->modify->n_fixes_style("bubble")) && (!registry.getLAMMPS()->atom->get_properties()->allow_soft_particles())) { if(strcmp(lmp->update->unit_style,"si") == 0 && Yi < 5e6) lmp->error->all(FLERR,"youngsModulus >= 5e6 required for SI units"); @@ -576,6 +653,13 @@ namespace MODEL_PARAMS /* ---------------------------------------------------------------------- */ + ScalarProperty* createLiquidDensity(PropertyRegistry & registry, const char * caller, bool) + { + return createScalarProperty(registry, LIQUID_DENSITY, caller); + } + + /* ---------------------------------------------------------------------- */ + ScalarProperty* createSurfaceTension(PropertyRegistry & registry, const char * caller, bool) { return createScalarProperty(registry, SURFACE_TENSION, caller); diff --git a/src/global_properties.h b/src/global_properties.h index f346d7662f2eaa784b6347d4cb75fb7287c9f373..0d8219c16192d38a86996b6357fd9592a3d12ac5 100644 --- a/src/global_properties.h +++ b/src/global_properties.h @@ -67,9 +67,12 @@ namespace MODEL_PARAMS /* ----------------------------------------------------------------------- * Property Creators * ----------------------------------------------------------------------- */ + VectorProperty* createCoalescenceModelSwitches(PropertyRegistry & registry, const char * caller, bool sanity_checks); + VectorProperty* createCoalescenceModelSettings(PropertyRegistry & registry, const char * caller, bool sanity_checks); MatrixProperty* createCohesionEnergyDensity(PropertyRegistry & registry, const char * caller, bool sanity_checks); VectorProperty* createCohesionDistanceSettings(PropertyRegistry & registry, const char * caller, bool sanity_checks); + VectorProperty* createCohesionModelSwitches(PropertyRegistry & registry, const char * caller, bool sanity_checks); ScalarProperty* createCharacteristicVelocity(PropertyRegistry & registry, const char * caller, bool sanity_checks); VectorProperty* createYoungsModulus(PropertyRegistry & registry, const char * caller, bool sanity_checks) ; VectorProperty* createPoissonsRatio(PropertyRegistry & registry, const char * caller, bool sanity_checks); @@ -88,6 +91,7 @@ namespace MODEL_PARAMS ScalarProperty* createRollingStiffness(PropertyRegistry & registry, const char * caller, bool sanity_checks); ScalarProperty* createLiquidVolume(PropertyRegistry & registry, const char * caller, bool sanity_checks); + ScalarProperty* createLiquidDensity(PropertyRegistry & registry, const char * caller, bool sanity_checks); ScalarProperty* createSurfaceTension(PropertyRegistry & registry, const char * caller, bool sanity_checks); ScalarProperty* createSwitchModel(PropertyRegistry & registry, const char * caller, bool sanity_checks); ScalarProperty* createHistoryIndex(PropertyRegistry & registry, const char * caller, bool sanity_checks); diff --git a/src/granular_pair_style.h b/src/granular_pair_style.h index 9f847fa97e2bbc37c35e536b60373f3cbd09d176..de5a8e4402889d66fcca5e9bdba72a4cde0c7198 100644 --- a/src/granular_pair_style.h +++ b/src/granular_pair_style.h @@ -62,7 +62,7 @@ namespace PairStyles { virtual void settings(int nargs, char ** args) = 0; virtual void init_granular() = 0; virtual void write_restart_settings(FILE * fp) = 0; - virtual void read_restart_settings(FILE * fp) = 0; + virtual void read_restart_settings(FILE * fp, int64_t hashcode = -1) = 0; virtual void compute_force(LAMMPS_NS::PairGran * pg, int eflag, int vflag, int addflag) = 0; virtual int bond_history_offset() = 0; diff --git a/src/granular_wall.h b/src/granular_wall.h index 7b37b2e69b0392d3ea4191d53ddd2fca1101311b..fbf5cbca7fcd70c70f341737e0b8fbac38d2514d 100644 --- a/src/granular_wall.h +++ b/src/granular_wall.h @@ -43,6 +43,7 @@ #include "utils.h" #include "tri_mesh.h" +#include "fix_mesh_surface.h" #include "contact_interface.h" namespace LAMMPS_NS { @@ -53,13 +54,15 @@ namespace LIGGGHTS { using namespace LAMMPS_NS; namespace Walls { + class IGranularWall { public: typedef FixWallGran ParentType; virtual ~IGranularWall(); virtual void settings(int nargs, char ** args) = 0; virtual void init_granular() = 0; - virtual void compute_force(FixWallGran * fwg, ContactModels::SurfacesIntersectData & sidata, double * v_wall,class TriMesh *mesh = 0,int iTri = 0) = 0; + virtual void compute_force(FixWallGran * wg, ContactModels::SurfacesIntersectData & sidata, bool intersectflag,double *vwall, + class FixMeshSurface * fix_mesh = 0, int iMesh = 0,class TriMesh *mesh = 0,int iTri = 0) = 0; }; class Factory : public Utils::AbstractFactory<IGranularWall> { diff --git a/src/group.cpp b/src/group.cpp index 667ed9952faf3b3014a87d7719f75d4fb3f1237a..493bd7731d931a8290c9c64376a8fd70bc3cec6f 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -422,7 +422,7 @@ void Group::assign(int narg, char **arg) add flagged atoms to a new or existing group ------------------------------------------------------------------------- */ -void Group::create(char *name, int *flag) +void Group::create(const char *name, int *flag) { int i; @@ -446,8 +446,41 @@ void Group::create(char *name, int *flag) int nlocal = atom->nlocal; int bit = bitmask[igroup]; - for (i = 0; i < nlocal; i++) - if (flag[i]) mask[i] |= bit; + if(flag) + { + for (i = 0; i < nlocal; i++) + if (flag[i]) mask[i] |= bit; + } +} + +/* ---------------------------------------------------------------------- + add flagged atoms to a new or existing group +------------------------------------------------------------------------- */ + +void Group::set(const char *name, bool flag) +{ + int igroup = find(name); + + if (igroup == -1) + if (ngroup == MAX_GROUP) error->all(FLERR,"Did not find group for 'set'"); + + // add atoms to group whose flags are set + + int *mask = atom->mask; + int nlocal = atom->nlocal; + int bit = bitmask[igroup]; + int invbit = inversemask[igroup]; + + if(flag) + { + for (int i = 0; i < nlocal; i++) + mask[i] |= bit; + } + else + { + for (int i = 0; i < nlocal; i++) + mask[i] &= invbit; + } } /* ---------------------------------------------------------------------- diff --git a/src/group.h b/src/group.h index 9ec626ff9e62e4ede55476ca019e3940c3a3a737..36928daa29850b6c3713dc71b02254a02bac879e 100644 --- a/src/group.h +++ b/src/group.h @@ -61,7 +61,8 @@ class Group : protected Pointers { Group(class LAMMPS *); ~Group(); void assign(int, char **); // assign atoms to a group - void create(char *, int *); // add flagged atoms to a group + void create(const char *, int *); // add flagged atoms to a group + void set(const char *name, bool flag); // set if all atoms belong to group or not int find(const char *); // lookup name in list of groups void write_restart(FILE *); void read_restart(FILE *); diff --git a/src/input.cpp b/src/input.cpp index 23b99746a21953a1162a7cc4d0294b7e11a94803..49b35291a382ee05443a33efe796f81a1bcbaa75 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -585,6 +585,7 @@ int Input::execute_command() else if (!strcmp(command,"dump_modify")) dump_modify(); else if (!strcmp(command,"fix")) fix(); else if (!strcmp(command,"fix_modify")) fix_modify(); + else if (!strcmp(command,"force_dt_reset")) force_dt_reset(); else if (!strcmp(command,"group")) group_command(); else if (!strcmp(command,"improper_coeff")) improper_coeff(); else if (!strcmp(command,"improper_style")) improper_style(); @@ -607,6 +608,7 @@ int Input::execute_command() else if (!strcmp(command,"reset_timestep")) reset_timestep(); else if (!strcmp(command,"restart")) restart(); else if (!strcmp(command,"run_style")) run_style(); + else if (!strcmp(command,"soft_particles")) soft_particles(); else if (!strcmp(command,"special_bonds")) special_bonds(); else if (!strcmp(command,"suffix")) suffix(); else if (!strcmp(command,"thermo")) thermo(); @@ -1300,6 +1302,20 @@ void Input::fix_modify() /* ---------------------------------------------------------------------- */ +void Input::force_dt_reset() +{ + if(narg != 1) + error->all(FLERR,"force_dt_reset expects 'yes' or 'no'"); + if(0 == strcmp(arg[0],"yes")) + update->set_force_dt_reset(true); + else if(0 == strcmp(arg[0],"no")) + update->set_force_dt_reset(false); + else + error->all(FLERR,"force_dt_reset expects 'yes' or 'no'"); +} + +/* ---------------------------------------------------------------------- */ + void Input::group_command() { group->assign(narg,arg); @@ -1568,6 +1584,20 @@ void Input::run_style() /* ---------------------------------------------------------------------- */ +void Input::soft_particles() +{ + if(narg != 1) + error->all(FLERR,"soft_particles expects 'yes' or 'no'"); + if(0 == strcmp(arg[0],"yes")) + atom->get_properties()->do_allow_soft_particles(); + else if(0 == strcmp(arg[0],"no")) + atom->get_properties()->do_not_allow_soft_particles(); + else + error->all(FLERR,"Soft_particles expects 'yes' or 'no'"); +} + +/* ---------------------------------------------------------------------- */ + void Input::special_bonds() { // store 1-3,1-4 and dihedral/extra flag values before change diff --git a/src/input.h b/src/input.h index 796aacee54827abd6d455141e348f5fa541b361b..769671c05692d6e11f9e8dd8756d595c82b0d74d 100644 --- a/src/input.h +++ b/src/input.h @@ -60,6 +60,9 @@ namespace LAMMPS_NS { class Input : protected Pointers { + + friend class Info; + public: int narg; // # of command args char **arg; // parsed args for command @@ -134,6 +137,7 @@ class Input : protected Pointers { void dump_modify(); void fix(); void fix_modify(); + void force_dt_reset(); void group_command(); void improper_coeff(); void improper_style(); @@ -157,6 +161,7 @@ class Input : protected Pointers { void reset_timestep(); void restart(); void run_style(); + void soft_particles(); void special_bonds(); void suffix(); void thermo(); diff --git a/src/input_mesh_tri.cpp b/src/input_mesh_tri.cpp index 2604bb96adc1e8b6326dc163ad03c452b1a7450a..15a28dddbb079dfa63ee8502cb5e10bc3ec04240 100644 --- a/src/input_mesh_tri.cpp +++ b/src/input_mesh_tri.cpp @@ -49,6 +49,7 @@ #include "modify.h" #include "update.h" #include "error.h" +#include "region.h" #include "domain.h" #include "math.h" #include "vector_liggghts.h" @@ -71,7 +72,9 @@ InputMeshTri::~InputMeshTri() process all input from filename ------------------------------------------------------------------------- */ -void InputMeshTri::meshtrifile(const char *filename, class TriMesh *mesh,bool verbose,const int size_exclusion_list, int *exclusion_list) +void InputMeshTri::meshtrifile(const char *filename, class TriMesh *mesh,bool verbose, + const int size_exclusion_list, int *exclusion_list, + class Region *region) { verbose_ = verbose; size_exclusion_list_ = size_exclusion_list; @@ -104,12 +107,13 @@ void InputMeshTri::meshtrifile(const char *filename, class TriMesh *mesh,bool ve if(is_stl) { if (comm->me == 0) fprintf(screen,"\nReading STL file '%s' \n",filename); - meshtrifile_stl(mesh); + meshtrifile_stl(mesh,region); + } else if(is_vtk) { if (comm->me == 0) fprintf(screen,"\nReading VTK file '%s' \n",filename); - meshtrifile_vtk(mesh); + meshtrifile_vtk(mesh,region); } else error->all(FLERR,"Illegal command, need either an STL file or a VTK file as input for triangular mesh."); @@ -120,7 +124,7 @@ void InputMeshTri::meshtrifile(const char *filename, class TriMesh *mesh,bool ve process VTK file ------------------------------------------------------------------------- */ -void InputMeshTri::meshtrifile_vtk(class TriMesh *mesh) +void InputMeshTri::meshtrifile_vtk(class TriMesh *mesh,class Region *region) { int n,m; @@ -284,6 +288,7 @@ void InputMeshTri::meshtrifile_vtk(class TriMesh *mesh) i_exclusion_list_++; continue; } + if(!region || ( region->match(points[cells[i][0]]) && region->match(points[cells[i][1]]) && region->match(points[cells[i][2]]) ) ) addTriangle(mesh,points[cells[i][0]],points[cells[i][1]],points[cells[i][2]],lines[i]); } @@ -295,7 +300,7 @@ void InputMeshTri::meshtrifile_vtk(class TriMesh *mesh) process STL file ------------------------------------------------------------------------- */ -void InputMeshTri::meshtrifile_stl(class TriMesh *mesh) +void InputMeshTri::meshtrifile_stl(class TriMesh *mesh,class Region *region) { int n,m; int iVertex = 0; @@ -308,6 +313,7 @@ void InputMeshTri::meshtrifile_stl(class TriMesh *mesh) while (1) { + // read a line from input script // n = length of line including str terminator, 0 if end of file // if line ends in continuation char '&', concatenate next line @@ -417,9 +423,14 @@ void InputMeshTri::meshtrifile_stl(class TriMesh *mesh) { if(i_exclusion_list_ < size_exclusion_list_-1) + { i_exclusion_list_++; + + while((exclusion_list_[i_exclusion_list_-1] == exclusion_list_[i_exclusion_list_]) && (i_exclusion_list_ < size_exclusion_list_-1)) + i_exclusion_list_++; + } } - else + else if(!region || ( region->match(vertices[0]) && region->match(vertices[1]) && region->match(vertices[2]) ) ) addTriangle(mesh,vertices[0],vertices[1],vertices[2],nLinesTri); if (me == 0) { diff --git a/src/input_mesh_tri.h b/src/input_mesh_tri.h index eb765124c65e709d57f73e677e6a0f2e88a4f911..6458daf59de1d7e4b0327f29c2943398d50e67c5 100644 --- a/src/input_mesh_tri.h +++ b/src/input_mesh_tri.h @@ -51,10 +51,12 @@ class InputMeshTri : protected Input { public: - InputMeshTri(class LAMMPS *, int, char **); + InputMeshTri(class LAMMPS *lmp, int narg, char **arg); ~InputMeshTri(); - void meshtrifile(const char *,class TriMesh *,bool verbose,const int size_exclusion_list, int *exclusion_list); + void meshtrifile(const char *filename,class TriMesh *mesh,bool verbose, + const int size_exclusion_list, int *exclusion_list, + class Region *region); private: @@ -63,8 +65,8 @@ class InputMeshTri : protected Input int size_exclusion_list_; int *exclusion_list_; - void meshtrifile_vtk(class TriMesh *); - void meshtrifile_stl(class TriMesh *); + void meshtrifile_vtk(class TriMesh *mesh,class Region *region); + void meshtrifile_stl(class TriMesh *mesh,class Region *region); inline void addTriangle(class TriMesh *mesh, double *a, double *b, double *c,int lineNumber); diff --git a/src/integrate.h b/src/integrate.h index 91d81e365be2cd6bf432c63c470030ab5501d46d..e909c7f88c2bfc40592599d2d9c0194a2c03e6fe 100644 --- a/src/integrate.h +++ b/src/integrate.h @@ -57,7 +57,7 @@ class Integrate : protected Pointers { virtual void init(); virtual void setup() = 0; virtual void setup_minimal(int) = 0; - virtual void run(int) = 0; + virtual void run(int nsteps) = 0; virtual void cleanup() {} virtual void reset_dt() {} virtual bigint memory_usage() {return 0;} diff --git a/src/lammps.cpp b/src/lammps.cpp index 71d89664c13d8e7b36e2c56b650d0998868f93f4..9cf679f577b6bd91e5fc65d85a03c70d85c27235 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -104,8 +104,11 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) screen = NULL; logfile = NULL; + infile = NULL; thermofile = NULL; + initclock = MPI_Wtime(); + // parse input switches int inflag = 0; @@ -247,7 +250,11 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) } else if (strcmp(arg[iarg],"-help") == 0 || strcmp(arg[iarg],"-h") == 0) { if (iarg+1 > narg) + { + if(screen) fprintf(screen,"argument is %s\n",arg[iarg]); + if(logfile) fprintf(logfile,"argument is %s\n",arg[iarg]); error->universe_all(FLERR,"Invalid command-line argument"); + } helpflag = 1; iarg += 1; } else error->universe_all(FLERR,"Invalid command-line argument"); diff --git a/src/lammps.h b/src/lammps.h index 83500dba3701c36c75ff9e72807cc4d212e5414f..49f7c0c00152314af014ab2c4c63c6612b04f3e8 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -75,6 +75,8 @@ class LAMMPS { FILE *logfile; // logfile FILE *thermofile; + double initclock; // wall clock at instantiation + char *suffix; // suffix to add to input script style names int suffix_enable; // 1 if suffix enabled, 0 if disabled int cite_enable; // 1 if generating log.cite, 0 if disabled diff --git a/src/lmpwindows.h b/src/lmpwindows.h index 59f15b15a48f2c8d7cf11211ba4f112731a2d66d..b6f28643d41a8a700e5f3cfe5b16f9310aed15da 100644 --- a/src/lmpwindows.h +++ b/src/lmpwindows.h @@ -24,9 +24,12 @@ // return pow((double)i,j); //} //#endif + +#if !defined(__MINGW32__) inline double sqrt(int i){ return sqrt((double) i); } +#if !defined(__MINGW32__) inline double fabs(int i){ return fabs((double) i); diff --git a/src/math_extra_liggghts.h b/src/math_extra_liggghts.h index f54c0f6cf7ca6ddcc180d6eebf07b1b5cdbc5cf2..de1b576636614c23e83a54e337fc29bcd078f10a 100644 --- a/src/math_extra_liggghts.h +++ b/src/math_extra_liggghts.h @@ -65,6 +65,9 @@ namespace MathExtraLiggghts { inline double cbrta_halleyd(const double a, const double R); inline double halley_cbrt1d(double d); + //exp aproximation + inline double exp_fast(double x); + inline int min(int a,int b); inline int max(int a,int b); inline int abs(int a); @@ -171,6 +174,18 @@ inline double MathExtraLiggghts::halley_cbrt1d(double d) return cbrta_halleyd(a, d); } +/* ---------------------------------------------------------------------- + exp approx +------------------------------------------------------------------------- */ + +inline double MathExtraLiggghts::exp_fast(double x) +{ + x = 1.0 + x / 256.0; + x *= x; x *= x; x *= x; x *= x; + x *= x; x *= x; x *= x; x *= x; + return x; +} + /* ---------------------------------------------------------------------- min max stuff ------------------------------------------------------------------------- */ diff --git a/src/modify.h b/src/modify.h index 12b210e146d7c2f1c305492122cbef2c5f21707b..607e728303e46821f3381a241537259683456ffb 100644 --- a/src/modify.h +++ b/src/modify.h @@ -61,6 +61,7 @@ namespace LAMMPS_NS { class Modify : protected Pointers { + friend class Info; public: int nfix,maxfix; int n_initial_integrate,n_post_integrate,n_pre_exchange,n_pre_neighbor; diff --git a/src/multi_node_mesh.h b/src/multi_node_mesh.h index 17939322227a10790fabcd3f00f4c9843e3b004a..8a996d2f05afb549b89a7dc964426a0baff3379e 100644 --- a/src/multi_node_mesh.h +++ b/src/multi_node_mesh.h @@ -69,6 +69,8 @@ namespace LAMMPS_NS void setPrecision(double _precision); + void setMinFeatureLength(double _min_feature_length); + void setElementExclusionList(FILE *_file); void autoRemoveDuplicates(); @@ -220,6 +222,9 @@ namespace LAMMPS_NS inline double precision() { return precision_; } + inline double minFeatureLength() + { return min_feature_length_; } + inline FILE* elementExclusionList() { return element_exclusion_list_; } @@ -228,6 +233,9 @@ namespace LAMMPS_NS // mesh precision double precision_; + // ignore features smaller than this size + double min_feature_length_; + FILE *element_exclusion_list_; // state if elements should be automatically removed if duplicate diff --git a/src/multi_node_mesh_I.h b/src/multi_node_mesh_I.h index 52ab640ae74ba1703a5ceca42cda3d4768b96ced..3ca0bef14f9aef4acb1beaff24082b2158aa8558 100644 --- a/src/multi_node_mesh_I.h +++ b/src/multi_node_mesh_I.h @@ -61,6 +61,7 @@ random_(new RanPark(lmp,179424799)), // big prime # mesh_id_(0), precision_(EPSILON_PRECISION), + min_feature_length_(-1.), element_exclusion_list_(0), autoRemoveDuplicates_(false), nMove_(0), @@ -102,6 +103,12 @@ precision_ = _precision; } + template<int NUM_NODES> + void MultiNodeMesh<NUM_NODES>::setMinFeatureLength(double _min_feature_length) + { + min_feature_length_ = _min_feature_length; + } + template<int NUM_NODES> void MultiNodeMesh<NUM_NODES>::setElementExclusionList(FILE *_file) { @@ -125,6 +132,10 @@ double avg[3]; + if(nodesAreEqual(nodeToAdd[0],nodeToAdd[1]) || nodesAreEqual(nodeToAdd[1],nodeToAdd[2]) || + nodesAreEqual(nodeToAdd[0],nodeToAdd[2]) ) + return false; + // add node node_.add(nodeToAdd); diff --git a/src/multi_node_mesh_parallel_I.h b/src/multi_node_mesh_parallel_I.h index 32b4094e3ae701dc57d9e3e431328893da6a2552..92e4410f23ccf95b8645127dd9e84febd64985e7 100644 --- a/src/multi_node_mesh_parallel_I.h +++ b/src/multi_node_mesh_parallel_I.h @@ -552,9 +552,10 @@ double span = this->node_.max_scalar()-this->node_.min_scalar(); if(span < 1e-4) - this->error->all(FLERR,"Mesh error: dimensions too small - use different unit system"); + this->error->all(FLERR,"Mesh error - root causes: (a) mesh empty or (b) dimensions too small - use different unit system"); // delete all elements that do not belong to this processor + deleteUnowned(); if(sizeGlobal() != sizeGlobalOrig()) @@ -568,9 +569,11 @@ } // perform operations that should be done before initial setup + preInitialSetup(); // set-up mesh parallelism + setup(); // re-calculate properties for owned particles @@ -583,6 +586,7 @@ borders(); // re-calculate properties for ghost particles + refreshGhosts(1); // build mesh topology and neigh list @@ -590,6 +594,7 @@ buildNeighbours(); // perform quality check on the mesh + qualityCheck(); if(doParallellization_) isParallel_ = true; @@ -597,8 +602,9 @@ postInitialSetup(); // stuff that should be done before resuming simulation + postBorders(); - + } /* ---------------------------------------------------------------------- diff --git a/src/multisphere.h b/src/multisphere.h index e236e0261c7ee3ef6cd4e603055f46cf4dee9f9e..f3f33113a48fa1f7bc3ff066db7fd1e34176d01b 100644 --- a/src/multisphere.h +++ b/src/multisphere.h @@ -53,6 +53,7 @@ namespace LAMMPS_NS { class Multisphere : protected Pointers { friend class FixMultisphere; + friend class FixChangeSizeMultisphere; public: @@ -151,6 +152,9 @@ namespace LAMMPS_NS { inline double density(int ibody_local) { return density_(ibody_local); } + inline double volume(int ibody_local) + { return masstotal_(ibody_local)/density_(ibody_local); } + inline void set_v_body(int ibody_local,double *vel) { vcm_.set(ibody_local,vel); } diff --git a/src/neigh_gran.cpp b/src/neigh_gran.cpp index 68fb55a260785af8a5a9b75f56fed03e19b1aa4c..7dc35bf9c46384ae2ea2be9a0aa3371900d21d5f 100644 --- a/src/neigh_gran.cpp +++ b/src/neigh_gran.cpp @@ -565,8 +565,11 @@ void Neighbor::granular_bin_no_newton(NeighList *list) // stores own/ghost pairs on both procs for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (j <= i) continue; + if (exclude && exclusion(i,j,type[i],type[j],mask,molecule)) continue; delx = xtmp - x[j][0]; @@ -575,7 +578,7 @@ void Neighbor::granular_bin_no_newton(NeighList *list) rsq = delx*delx + dely*dely + delz*delz; radsum = (radi + radius[j]) * contactDistanceFactor; cutsq = (radsum+skin) * (radsum+skin); - + if (rsq <= cutsq) { neighptr[n] = j; @@ -629,6 +632,7 @@ void Neighbor::granular_bin_no_newton(NeighList *list) ipage_contact_flag->vgot(n); dpage_contact_hist->vgot(nn); } + } list->inum = inum; diff --git a/src/normal_model_hertz.h b/src/normal_model_hertz.h index 13a7c51b27f71e7406ebff175908744ba4e3c031..0aece0dc19e5f5ac608ef21f30d74247a53b9467 100644 --- a/src/normal_model_hertz.h +++ b/src/normal_model_hertz.h @@ -75,6 +75,7 @@ namespace ContactModels void registerSettings(Settings & settings) { + settings.registerOnOff("tangential_damping", tangential_damping, true); settings.registerOnOff("limitForce", limitForce); settings.registerOnOff("heating_normal_hertz",heating,false); @@ -82,7 +83,11 @@ namespace ContactModels //TODO error->one(FLERR,"TODO here also check if right surface model used"); } - void connectToProperties(PropertyRegistry & registry) { + inline void postSettings() {} + + void connectToProperties(PropertyRegistry & registry) + { + registry.registerProperty("Yeff", &MODEL_PARAMS::createYeff,"model hertz"); registry.registerProperty("Geff", &MODEL_PARAMS::createGeff,"model hertz"); registry.registerProperty("betaeff", &MODEL_PARAMS::createBetaEff,"model hertz"); @@ -90,6 +95,7 @@ namespace ContactModels registry.connect("Yeff", Yeff,"model hertz"); registry.connect("Geff", Geff,"model hertz"); registry.connect("betaeff", betaeff,"model hertz"); + } // effective exponent for stress-strain relationship @@ -101,6 +107,14 @@ namespace ContactModels inline void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces) { + + //if(!sidata.is_wall) // bond_history_offset_ >= 0) + //{ + //double * const bond_contact_flag = &sidata.contact_history[bond_history_offset_]; + //if(!MathExtraLiggghts::compDouble(bond_contact_flag[0],0.)) + // return; + //} + const int itype = sidata.itype; const int jtype = sidata.jtype; double ri = sidata.radi; @@ -228,6 +242,7 @@ namespace ContactModels bool heating; bool heating_track; class ContactModelBase *cmb; + }; } diff --git a/src/normal_model_hertz_stiffness.h b/src/normal_model_hertz_stiffness.h index a97e647318a3cc66a7336fcbcf07954fa2b66248..16f60f6a1af2d5fc85fdbb6f9c61a54be318df96 100644 --- a/src/normal_model_hertz_stiffness.h +++ b/src/normal_model_hertz_stiffness.h @@ -77,6 +77,8 @@ namespace ContactModels settings.registerOnOff("limitForce", limitForce); } + inline void postSettings() {} + void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("k_n", &MODEL_PARAMS::createKn); diff --git a/src/normal_model_hooke.h b/src/normal_model_hooke.h index 6ecfe9912bb8d8d1f8b06a10e8c7e11c0558c4e4..d0a3320d9b41497e5dab098a9a3eac860372e32e 100644 --- a/src/normal_model_hooke.h +++ b/src/normal_model_hooke.h @@ -94,6 +94,8 @@ namespace ContactModels settings.registerOnOff("heating_tracking",heating_track,false); } + inline void postSettings() {} + inline void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("Yeff", &MODEL_PARAMS::createYeff); registry.registerProperty("Geff", &MODEL_PARAMS::createGeff); diff --git a/src/normal_model_hooke_hysteresis.h b/src/normal_model_hooke_hysteresis.h index 987e69672061b0632836511927682269b101d0b8..14f722be2e71617060b95fffa2a1338d0101a1a0 100644 --- a/src/normal_model_hooke_hysteresis.h +++ b/src/normal_model_hooke_hysteresis.h @@ -76,6 +76,8 @@ namespace ContactModels NormalModel<HOOKE>::registerSettings(settings); } + inline void postSettings() {} + inline void connectToProperties(PropertyRegistry & registry) { NormalModel<HOOKE>::connectToProperties(registry); diff --git a/src/normal_model_hooke_stiffness.h b/src/normal_model_hooke_stiffness.h index 1b7cb76a4088b8d695ae31c02e1b499776e65189..9ef99625418d3ce1cff91265e603301358533543 100644 --- a/src/normal_model_hooke_stiffness.h +++ b/src/normal_model_hooke_stiffness.h @@ -77,6 +77,8 @@ namespace ContactModels settings.registerOnOff("limitForce", limitForce); } + inline void postSettings() {} + void connectToProperties(PropertyRegistry & registry) { registry.registerProperty("k_n", &MODEL_PARAMS::createKn); registry.registerProperty("k_t", &MODEL_PARAMS::createKt); diff --git a/src/pair_gran.cpp b/src/pair_gran.cpp index 8984747a1e4c14d656339af6a210bef95832b965..0e591ab93109a1e87d24ab56fa2e58d0a1d09a1e 100644 --- a/src/pair_gran.cpp +++ b/src/pair_gran.cpp @@ -603,6 +603,7 @@ void PairGran::compute(int eflag, int vflag) void PairGran::compute_pgl(int eflag, int vflag) { + // update rigid body info for owned & ghost atoms if using FixRigid masses // body[i] = which body atom I is in, -1 if none // mass_body = mass of each rigid body diff --git a/src/pair_gran_base.h b/src/pair_gran_base.h index de5a14fc85d501f1758aa383ef3e8bcd9a17a548..33fe26f7100c05b61acfade28d019d4a1a42715f 100644 --- a/src/pair_gran_base.h +++ b/src/pair_gran_base.h @@ -148,16 +148,21 @@ public: fwrite(&hashcode, sizeof(int64_t), 1, fp); } - virtual void read_restart_settings(FILE * fp) + virtual void read_restart_settings(FILE * fp, int64_t hashcode) { int me = comm->me; - int64_t hashcode = -1; + int64_t selected = -1; if(me == 0){ - size_t dummy = fread(&hashcode, sizeof(int64_t), 1, fp); + size_t dummy = fread(&selected, sizeof(int64_t), 1, fp); UNUSED(dummy); // sanity check - if(hashcode != ContactModel::STYLE_HASHCODE) - error->all(FLERR,"wrong pair style loaded!"); + if(hashcode != -1) { // backward compability + if(hashcode != ContactModel::STYLE_HASHCODE) + error->one(FLERR,"wrong pair style loaded!"); + } else { + if(selected != ContactModel::STYLE_HASHCODE) + error->one(FLERR,"wrong pair style loaded!"); + } } } @@ -287,7 +292,7 @@ public: // rsq < radsum * radsum is broad phase check with bounding spheres // cmodel.checkSurfaceIntersect() is narrow phase check -#ifdef SUPERQUADRIC_ACTIVE_FLAG + #ifdef SUPERQUADRIC_ACTIVE_FLAG sidata.v_i = v[i]; sidata.v_j = v[j]; if (rmass) { @@ -299,7 +304,7 @@ public: } sidata.omega_i = omega[i]; sidata.omega_j = omega[j]; -#endif + #endif if (rsq < radsum * radsum && cmodel.checkSurfaceIntersect(sidata)) { const double r = sqrt(rsq); const double rinv = 1.0 / r; diff --git a/src/pair_gran_proxy.cpp b/src/pair_gran_proxy.cpp index 79135042f3ad2281f436ae6e646fc4626fd7108f..b6624f9cc352c5a6d2df41ccee604ddbf04c1ab0 100644 --- a/src/pair_gran_proxy.cpp +++ b/src/pair_gran_proxy.cpp @@ -46,6 +46,7 @@ #include "pair_gran_proxy.h" #include "granular_pair_style.h" +#include "contact_models.h" using namespace LAMMPS_NS; using namespace LIGGGHTS::PairStyles; @@ -70,7 +71,13 @@ void PairGranProxy::settings(int nargs, char ** args) impl->settings(nargs, args); } else { - error->one(FLERR, "unknown contact model"); + error->all(FLERR, "unknown contact model or model not in whitelist. Possible root causes:\n" + " (1) it's a typo. Check the documentation of the contact model you are using.\n" + " (2) the contact model is not available in your installation. Check if a documentation for this.\n" + " contact model is available at all in your version.\n" + " (3) the model is part of a package which was not installed. Check the documentation for details. \n" + " (4) the model is available, but was not in the whitelist during compilation. Check if a file \n" + " src/style_contact_model.whitelist exists. If yes, modify it and re-compile.\n"); } } @@ -88,7 +95,7 @@ void PairGranProxy::read_restart_settings(FILE * fp) { int me = comm->me; - int64_t selected = -1; + int64_t selected = -1, used = -1; if(me == 0){ // read model hashcode, but reset file pointer afterwards. // this way read_restart_settings can still read the hashcode (sanity check) @@ -99,8 +106,24 @@ void PairGranProxy::read_restart_settings(FILE * fp) impl = Factory::instance().create("gran", selected, lmp, this); + // convert if not found + if(!impl) { + const int M = (15) & selected; + const int T = (15) & selected >> 4; + const int C = (15) & selected >> 8; + const int R = (15) & selected >> 12; + const int S = (15) & selected >> 16; + error->warning(FLERR, "LIGGGHTS tries to use old-style hashcode to find the contact model. Update your restart file."); + if(screen) { + fprintf(screen," original hashcode = %zd \n",selected); + fprintf(screen," M = %d, T = %d, C = %d, R = %d, S = %d \n",M,T,C,R,S); + } + used = ::LIGGGHTS::ContactModels::generate_gran_hashcode(M,T,C,R,S); + impl = Factory::instance().create("gran", used, lmp, this); + } + if(impl) { - impl->read_restart_settings(fp); + impl->read_restart_settings(fp, used); } else { error->one(FLERR, "unknown contact model"); } diff --git a/src/pair_sph_artvisc_tenscorr.cpp b/src/pair_sph_artvisc_tenscorr.cpp index 94f19169416c8f0cdaa050616c533b7b943fe9a1..83612c1c015aaadc0ab14e151037cfabcafb6d64 100644 --- a/src/pair_sph_artvisc_tenscorr.cpp +++ b/src/pair_sph_artvisc_tenscorr.cpp @@ -224,9 +224,9 @@ void PairSphArtviscTenscorr::init_substyle() etaPPG=static_cast<FixPropertyGlobal*>(modify->find_fix_property("artViscEta","property/global","scalar",0,0,force->pair_style)); if(!etaPPG) error->all(FLERR, "Pairstyle sph/artVisc/tensCorr only works with a fix property/global that defines artViscEta"); - eta = etaPPG->compute_scalar(); // NP const for all type + eta = etaPPG->compute_scalar(); - viscosity_ = 1; // NP dummy + viscosity_ = 1; //viscosity_ = alpha; //pre-calculate parameters for possible contact material combinations diff --git a/src/particleToInsert.cpp b/src/particleToInsert.cpp index 448a2d7e576b64b437588aa158b8be1c95f30996..7ceab92479ea8d3c0e9e2d234980a4fc178ba3a6 100644 --- a/src/particleToInsert.cpp +++ b/src/particleToInsert.cpp @@ -222,7 +222,7 @@ int ParticleToInsert::check_near_set_x_v_omega_ms(double *x,double *v, double *o /* ---------------------------------------------------------------------- */ -int ParticleToInsert::check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList) +int ParticleToInsert::check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList) { if(nspheres > 1) return check_near_set_x_v_omega_ms(x,v, omega,quat,neighList); @@ -245,7 +245,7 @@ int ParticleToInsert::check_near_set_x_v_omega(double *x,double *v, double *omeg /* ---------------------------------------------------------------------- */ -int ParticleToInsert::check_near_set_x_v_omega_ms(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList) +int ParticleToInsert::check_near_set_x_v_omega_ms(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList) { // x is position where insertion should take place // v and omega are the velocity and omega for the newly inserted particles diff --git a/src/particleToInsert.h b/src/particleToInsert.h index 846fa7f4e93f192fc75808ec9490511ed5b54ae7..bc7075b873c2e2f947da904129ff8ed3e5cb9fcf 100644 --- a/src/particleToInsert.h +++ b/src/particleToInsert.h @@ -91,8 +91,8 @@ namespace LAMMPS_NS { double fix_property_value; virtual int insert(); - virtual int check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList); - virtual int check_near_set_x_v_omega_ms(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList); + virtual int check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList); + virtual int check_near_set_x_v_omega_ms(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList); //virtual int check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, double **xnear, int &nnear); //virtual int check_near_set_x_v_omega_ms(double *x,double *v, double *omega, double *quat, double **xnear, int &nnear); diff --git a/src/particleToInsert_multisphere.cpp b/src/particleToInsert_multisphere.cpp index 21e1a229a1888f12cce4409fb03dab4409a14947..aa12a00c4b9a77b48448c60082c62c956d991e3f 100644 --- a/src/particleToInsert_multisphere.cpp +++ b/src/particleToInsert_multisphere.cpp @@ -103,7 +103,7 @@ int ParticleToInsertMultisphere::set_x_v_omega(double *x, double *v, double *ome /* ---------------------------------------------------------------------- */ -int ParticleToInsertMultisphere::check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList)//, double **xnear, int &nnear) +int ParticleToInsertMultisphere::check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList)//, double **xnear, int &nnear) { // check every sphere against all others in xnear diff --git a/src/particleToInsert_multisphere.h b/src/particleToInsert_multisphere.h index ae070954a162a4bd88d312620088b6d8ce155c5a..40c1bae2df2b35a7e40e0ab797fec0bd2f87bb37 100644 --- a/src/particleToInsert_multisphere.h +++ b/src/particleToInsert_multisphere.h @@ -76,7 +76,7 @@ namespace LAMMPS_NS { int type_ms; int insert(); - int check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList & neighList);//, double **xnear, int &nnear) + int check_near_set_x_v_omega(double *x,double *v, double *omega, double *quat, RegionNeighborList<interpolate_no> & neighList);//, double **xnear, int &nnear) int set_x_v_omega(double *,double *,double *, double *); void random_rotate(double,double,double); diff --git a/src/properties.cpp b/src/properties.cpp index 1f1f6856326d5fbed318260e1b35b2491876e115..214d63928056312541c312cc4da199f8d102e804 100644 --- a/src/properties.cpp +++ b/src/properties.cpp @@ -60,7 +60,10 @@ using namespace LAMMPS_NS; Properties::Properties(LAMMPS *lmp): Pointers(lmp), ms_(0), - ms_data_(0) + ms_data_(0), + mintype_(-1), + maxtype_(-1), + allow_soft_particles_(false) { } @@ -80,15 +83,15 @@ Properties::~Properties() int Properties::max_type() { // loop over all particles to check how many atom types are present - mintype = 100000; - maxtype = 1; + mintype_ = 100000; + maxtype_ = 1; for (int i=0;i<atom->nlocal;i++) { - if (atom->type[i]<mintype) - mintype=atom->type[i]; - if (atom->type[i]>maxtype) - maxtype=atom->type[i]; + if (atom->type[i]<mintype_) + mintype_=atom->type[i]; + if (atom->type[i]>maxtype_) + maxtype_=atom->type[i]; } // check all fixes @@ -97,26 +100,26 @@ int Properties::max_type() { // checks Fix *fix = modify->fix[i]; - if(fix->min_type() > 0 && fix->min_type() < mintype) - mintype = fix->min_type(); - if(fix->max_type() > 0 && fix->max_type() > maxtype) - maxtype = fix->max_type(); + if(fix->min_type() > 0 && fix->min_type() < mintype_) + mintype_ = fix->min_type(); + if(fix->max_type() > 0 && fix->max_type() > maxtype_) + maxtype_ = fix->max_type(); } //Get min/max from other procs int mintype_all,maxtype_all; - MPI_Allreduce(&mintype,&mintype_all, 1, MPI_INT, MPI_MIN, world); - MPI_Allreduce(&maxtype,&maxtype_all, 1, MPI_INT, MPI_MAX, world); - mintype = mintype_all; - maxtype = maxtype_all; + MPI_Allreduce(&mintype_,&mintype_all, 1, MPI_INT, MPI_MIN, world); + MPI_Allreduce(&maxtype_,&maxtype_all, 1, MPI_INT, MPI_MAX, world); + mintype_ = mintype_all; + maxtype_ = maxtype_all; //error check - if(mintype != 1) + if(mintype_ != 1) error->all(FLERR,"Atom types must start from 1 for granular simulations"); - if(maxtype > atom->ntypes) + if(maxtype_ > atom->ntypes) error->all(FLERR,"Please increase the number of atom types in the 'create_box' command to match the number of atom types you use in the simulation"); - return maxtype; + return maxtype_; } /* ---------------------------------------------------------------------- diff --git a/src/properties.h b/src/properties.h index 79911182c5cda7f8682d94cdc9bc7db5a831ba52..7c7d6b6968b6d8dbe5a0f0bc8fe052b8d9052111 100644 --- a/src/properties.h +++ b/src/properties.h @@ -59,13 +59,23 @@ class Properties: protected Pointers void* find_property(const char *name, const char *type, int &len1, int &len2); inline class Multisphere *ms_data() { return ms_data_;} + bool allow_soft_particles() + { return allow_soft_particles_; } + + void do_allow_soft_particles() + { allow_soft_particles_ = true; } + void do_not_allow_soft_particles() + { allow_soft_particles_ = false; } + private: // multisphere class FixMultisphere *ms_; class Multisphere *ms_data_; - int mintype,maxtype; + int mintype_,maxtype_; + + bool allow_soft_particles_; }; //end class } diff --git a/src/read_dump.cpp b/src/read_dump.cpp index 53599095fba57b203c16ff647576aa6a670a4daf..131cf99a7579b618c473212a183b97bc6721ca32 100644 --- a/src/read_dump.cpp +++ b/src/read_dump.cpp @@ -51,6 +51,7 @@ #include "mpi.h" #include "string.h" #include "stdlib.h" +#include "dirent.h" #include "read_dump.h" #include "reader.h" #include "style_reader.h" @@ -72,7 +73,7 @@ using namespace LAMMPS_NS; // also in reader_native.cpp -enum{ID,TYPE,X,Y,Z,VX,VY,VZ,Q,IX,IY,IZ}; +enum{ID,TYPE,X,Y,Z,VX,VY,VZ,Q,IX,IY,IZ,RADIUS,MASS,DENSITY}; enum{UNSET,NOSCALE_NOWRAP,NOSCALE_WRAP,SCALE_NOWRAP,SCALE_WRAP}; /* ---------------------------------------------------------------------- */ @@ -201,6 +202,13 @@ void ReadDump::command(int narg, char **arg) void ReadDump::store_files(int nstr, char **str) { + + if(strrchr(str[0],'*')) + { + file_search(str[0]); + return; + } + nfile = nstr; files = new char*[nfile]; @@ -211,6 +219,117 @@ void ReadDump::store_files(int nstr, char **str) } } +/* ---------------------------------------------------------------------- + infile contains a "*" + search for all files which match the infile pattern + replace "*" with any timestep value + search dir referenced by initial pathname of file +------------------------------------------------------------------------- */ + +void ReadDump::file_search(char *infile) +{ + char *ptr; + + files = new char*[10000]; + int *middle_index = new int[10000]; + + // separate infile into dir + filename + + char *dirname = new char[strlen(infile) + 1]; + char *filename = new char[strlen(infile) + 1]; + + if (strchr(infile,'/')) { + ptr = strrchr(infile,'/'); + *ptr = '\0'; + strcpy(dirname,infile); + strcpy(filename,ptr+1); + *ptr = '/'; + } else { + strcpy(dirname,"./"); + strcpy(filename,infile); + } + + char *pattern = new char[strlen(filename) + 1]; + strcpy(pattern,filename); + + // scan all files in directory, searching for files that match pattern + // maxnum = largest int that matches "*" + + size_t n = strlen(pattern) + 16; + char *begin = new char[n]; + char *middle = new char[n]; + char *end = new char[n]; + + ptr = strchr(pattern,'*'); + *ptr = '\0'; + strcpy(begin,pattern); + strcpy(end,ptr+1); + int nbegin = strlen(begin); + nfile = 0; + + struct dirent *ep; + DIR *dp = opendir(dirname); + if (dp == NULL) + error->one(FLERR,"Cannot open dir to search for dump file"); + + while ((ep = readdir(dp))) { + if (strstr(ep->d_name,begin) != ep->d_name) continue; + if ((ptr = strstr(&ep->d_name[nbegin],end)) == NULL) continue; + if (strlen(end) == 0) ptr = ep->d_name + strlen(ep->d_name); + *ptr = '\0'; + if (strlen(&ep->d_name[nbegin]) < n) { + strcpy(middle,&ep->d_name[nbegin]); + + nfile++; + + if(nfile >= 10000) + error->one(FLERR,"Currently max. 10000 dump files matching pattern can be read"); + + files[nfile-1] = new char[strlen(filename) + 16]; + middle_index[nfile-1] = atoi(middle); + sprintf(files[nfile-1],"%s/%s%s%s",dirname,begin,middle,end); + + } + } + closedir(dp); + if (nfile <= 0) error->one(FLERR,"Found no dump file matching pattern"); + + bool swaped; + int nswaps_left = nfile; + do + { + swaped = false; + for(int i = 0; i < nfile-1; i++) + { + if(middle_index[i] > middle_index[i+1]) + { + //swap + char swapper[512]; + strcpy(swapper,files[i+1]); + strcpy(files[i+1],files[i]); + strcpy(files[i],swapper); + + int swapper_i = middle_index[i+1]; + middle_index[i+1] = middle_index[i]; + middle_index[i] = swapper_i; + + swaped = true; + } + } + nswaps_left--; + } while(swaped && nswaps_left > 0); + + // clean up + + delete [] dirname; + delete [] filename; + delete [] pattern; + delete [] begin; + delete [] middle; + delete [] end; + delete [] middle_index; +} + /* ---------------------------------------------------------------------- */ void ReadDump::setup_reader(int narg, char **arg) @@ -609,7 +728,7 @@ int ReadDump::fields_and_keywords(int narg, char **arg) nfield = 0; fieldtype[nfield++] = ID; - if (iarg < narg) fieldtype[nfield++] = TYPE; + /*if (iarg < narg)*/ fieldtype[nfield++] = TYPE; // parse fields @@ -626,6 +745,21 @@ int ReadDump::fields_and_keywords(int narg, char **arg) error->all(FLERR,"Read dump of atom property that isn't allocated"); fieldtype[nfield++] = Q; } + else if (strcmp(arg[iarg],"radius") == 0) { + if (!atom->radius_flag) + error->all(FLERR,"Read dump of atom property that isn't allocated"); + fieldtype[nfield++] = RADIUS; + } + else if (strcmp(arg[iarg],"mass") == 0) { + if (!atom->rmass_flag) + error->all(FLERR,"Read dump of atom property that isn't allocated"); + fieldtype[nfield++] = MASS; + } + else if (strcmp(arg[iarg],"density") == 0) { + if (!atom->density_flag) + error->all(FLERR,"Read dump of atom property that isn't allocated"); + fieldtype[nfield++] = DENSITY; + } else if (strcmp(arg[iarg],"ix") == 0) fieldtype[nfield++] = IX; else if (strcmp(arg[iarg],"iy") == 0) fieldtype[nfield++] = IY; else if (strcmp(arg[iarg],"iz") == 0) fieldtype[nfield++] = IZ; @@ -748,6 +882,9 @@ void ReadDump::process_atoms(int n) double **x = atom->x; double **v = atom->v; double *q = atom->q; + double *radius = atom->radius; + double *rmass= atom->rmass; + double *density= atom->density; tagint *image = atom->image; int nlocal = atom->nlocal; int map_tag_max = atom->map_tag_max; @@ -792,15 +929,24 @@ void ReadDump::process_atoms(int n) case VX: v[m][0] = fields[i][ifield]; break; - case Q: - q[m] = fields[i][ifield]; - break; case VY: v[m][1] = fields[i][ifield]; break; case VZ: v[m][2] = fields[i][ifield]; break; + case Q: + q[m] = fields[i][ifield]; + break; + case RADIUS: + radius[m] = fields[i][ifield]; + break; + case MASS: + rmass[m] = fields[i][ifield]; + break; + case DENSITY: + density[m] = fields[i][ifield]; + break; case IX: xbox = static_cast<int> (fields[i][ifield]); break; @@ -873,6 +1019,9 @@ void ReadDump::process_atoms(int n) v = atom->v; q = atom->q; + radius = atom->radius; + rmass = atom->rmass; + density = atom->density; image = atom->image; // set atom attributes from other dump file fields @@ -893,6 +1042,15 @@ void ReadDump::process_atoms(int n) case Q: q[m] = fields[i][ifield]; break; + case RADIUS: + radius[m] = fields[i][ifield]; + break; + case MASS: + rmass[m] = fields[i][ifield]; + break; + case DENSITY: + density[m] = fields[i][ifield]; + break; case IX: xbox = static_cast<int> (fields[i][ifield]); break; diff --git a/src/read_dump.h b/src/read_dump.h index 1607adb0fd290756ab2f665458d771b18159be90..03d235c5635c9afc49c7c4f89fa02c61b1aa5308 100644 --- a/src/read_dump.h +++ b/src/read_dump.h @@ -58,6 +58,8 @@ CommandStyle(read_dump,ReadDump) namespace LAMMPS_NS { class ReadDump : protected Pointers { + friend class Rerun; + public: ReadDump(class LAMMPS *); ~ReadDump(); @@ -72,6 +74,9 @@ class ReadDump : protected Pointers { int fields_and_keywords(int, char **); private: + + void file_search(char *infile); + int me,nprocs; FILE *fp; diff --git a/src/reader_native.cpp b/src/reader_native.cpp index 99c0fe251ad069dd8e7ea54a0af0fffe20cd18a0..1c94d2bd8cb1aa2f902c39667d9e9627fe0a7312 100644 --- a/src/reader_native.cpp +++ b/src/reader_native.cpp @@ -56,7 +56,7 @@ using namespace LAMMPS_NS; // also in read_dump.cpp -enum{ID,TYPE,X,Y,Z,VX,VY,VZ,Q,IX,IY,IZ}; +enum{ID,TYPE,X,Y,Z,VX,VY,VZ,Q,IX,IY,IZ,RADIUS,MASS,DENSITY}; enum{UNSET,NOSCALE_NOWRAP,NOSCALE_WRAP,SCALE_NOWRAP,SCALE_WRAP}; /* ---------------------------------------------------------------------- */ @@ -173,10 +173,16 @@ bigint ReaderNative::read_header(double box[3][3], int &triclinic, nwords = atom->count_words(labelline); char **labels = new char*[nwords]; labels[0] = strtok(labelline," \t\n\r\f"); - if (labels[0] == NULL) return 1; + if (labels[0] == NULL) { + delete[] labels; + return 1; + } for (int m = 1; m < nwords; m++) { labels[m] = strtok(NULL," \t\n\r\f"); - if (labels[m] == NULL) return 1; + if (labels[m] == NULL) { + delete[] labels; + return 1; + } } // match each field with a column of per-atom data @@ -283,6 +289,15 @@ bigint ReaderNative::read_header(double box[3][3], int &triclinic, else if (fieldtype[i] == Q) fieldindex[i] = find_label("q",nwords,labels); + else if (fieldtype[i] == RADIUS) + fieldindex[i] = find_label("radius",nwords,labels); + + else if (fieldtype[i] == MASS) + fieldindex[i] = find_label("mass",nwords,labels); + + else if (fieldtype[i] == DENSITY) + fieldindex[i] = find_label("density",nwords,labels); + else if (fieldtype[i] == IX) fieldindex[i] = find_label("ix",nwords,labels); else if (fieldtype[i] == IY) @@ -350,13 +365,13 @@ int ReaderNative::find_label(const char *label, int n, char **labels) /* ---------------------------------------------------------------------- read N lines from dump file only last one is saved in line - return NULL if end-of-file error, else non-NULL only called by proc 0 ------------------------------------------------------------------------- */ void ReaderNative::read_lines(int n) { char *eof = NULL; + if (n <= 0) return; for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp); - if (eof == NULL) error->all(FLERR,"Unexpected end of dump file"); + if (eof == NULL) error->one(FLERR,"Unexpected end of dump file"); } diff --git a/src/region.h b/src/region.h index 66a3d3c80a73d045e0978feb18da8dbca6e4a298..75841ddd7bdde97729d5dc78190116b5554c1ce3 100644 --- a/src/region.h +++ b/src/region.h @@ -84,6 +84,9 @@ class Region : protected Pointers { // called by other classes to check point versus region + inline int match(double *point) + { return match(point[0],point[1],point[2]);} + int match(double, double, double); int surface(double, double, double, double); diff --git a/src/region_mesh_tet.cpp b/src/region_mesh_tet.cpp index bf63097c5825bcbb4d0ebfc33930392fe162ba55..c29a59bee42d618ef06b0f329e492c85278ff266 100644 --- a/src/region_mesh_tet.cpp +++ b/src/region_mesh_tet.cpp @@ -44,7 +44,6 @@ #include "region_mesh_tet.h" #include "lammps.h" #include "bounding_box.h" -#include "region_neighbor_list.h" #include "tri_mesh.h" #include "memory.h" #include "error.h" @@ -65,7 +64,7 @@ using namespace LAMMPS_NS; RegTetMesh::RegTetMesh(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg), bounding_box_mesh(*new BoundingBox(BIG,-BIG,BIG,-BIG,BIG,-BIG)), - neighList(*new RegionNeighborList(lmp)), + neighList(*new RegionNeighborList<interpolate_no>(lmp)), tri_mesh(*new TriMesh(lmp)) { if(narg < 14) error->all(FLERR,"Illegal region mesh/tet command"); @@ -230,6 +229,7 @@ void RegTetMesh::generate_random_shrinkby_cut(double *pos,double cut,bool subdom { int ntry = 0; bool is_near_surface = false; + int barysign = -1; for(int i = 0; i < nTet; i++) { @@ -249,7 +249,7 @@ void RegTetMesh::generate_random_shrinkby_cut(double *pos,double cut,bool subdom { int iSurf = surfaces[iTetChosen][is]; - if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta) < 0) + if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta,barysign) < 0) { is_near_surface = true; break; @@ -267,7 +267,7 @@ void RegTetMesh::generate_random_shrinkby_cut(double *pos,double cut,bool subdom { int iSurf = surfaces[face_neighs[iTetChosen][iFaceNeigh]][is]; - if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta) < 0) + if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta,barysign) < 0) { is_near_surface = true; break; @@ -286,7 +286,7 @@ void RegTetMesh::generate_random_shrinkby_cut(double *pos,double cut,bool subdom { int iSurf = surfaces[node_neighs[iTetChosen][iNodeNeigh]][is]; - if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta) < 0) + if(tri_mesh.resolveTriSphereContact(-1,iSurf,cut,pos,delta,barysign) < 0) { is_near_surface = true; break; @@ -345,7 +345,7 @@ void RegTetMesh::add_tet(double **n) void RegTetMesh::build_neighs() { - neighList.clear(); + neighList.reset(); for(int i = 0; i < nTet; i++) { diff --git a/src/region_mesh_tet.h b/src/region_mesh_tet.h index b9ed8e5705126a31f29d1fe72af289917f302da4..2514c4b95e619283770197ce02194a37429e88d3 100644 --- a/src/region_mesh_tet.h +++ b/src/region_mesh_tet.h @@ -50,6 +50,7 @@ RegionStyle(mesh/tet,RegTetMesh) #include "random_park.h" #include "region.h" +#include "region_neighbor_list.h" namespace LAMMPS_NS { @@ -122,7 +123,7 @@ class RegTetMesh : public Region { class BoundingBox &bounding_box_mesh; - class RegionNeighborList &neighList; + class RegionNeighborList<interpolate_no> &neighList; class TriMesh &tri_mesh; diff --git a/src/region_neighbor_list.cpp b/src/region_neighbor_list.cpp index f232a327386b3f57855610e4f31c71f4b2ff88a8..eda90fe3c7ac079056a4ad51cad369747a30aac9 100644 --- a/src/region_neighbor_list.cpp +++ b/src/region_neighbor_list.cpp @@ -35,485 +35,6 @@ (if not contributing author is listed, this file has been contributed by the core developer) - Richard Berger (JKU Linz) - Christoph Kloss (DCS Computing GmbH) - Alexander Podlozhnyuk (DCS Computing GmbH) - - Copyright 2014-2015 JKU Linz - Copyright 2015- DCS Computing GmbH + Copyright 2015- DCS Computing GmbH, Linz ------------------------------------------------------------------------- */ -#include "lmptype.h" -#include "mpi.h" -#include "bounding_box.h" -#include "error.h" -#include "region_neighbor_list.h" -#include <limits> -#include <algorithm> -#ifdef SUPERQUADRIC_ACTIVE_FLAG -#include "math_extra_liggghts_superquadric.h" -#endif - -static const double SMALL = 1.0e-6; -static const double BIG = 1.0e20; - -using namespace LAMMPS_NS; -using namespace std; - -/** - * @brief Default constructor which will create an empty neighbor list - */ -RegionNeighborList::RegionNeighborList(LAMMPS *lmp) : - Pointers(lmp), - bbox_set(false) -{ -} - -/** - * @brief Determine if the given particle overlaps with any particle in this neighbor list - * @param x position of particle to check - * @param radius radius of particle to check - * @return true if particle has an overlap with a particle in this neighbor list, false otherwise - */ -bool RegionNeighborList::hasOverlap(double * x, double radius) const { - int ibin = coord2binLocal(x); - - for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) { - const int offset = *it; - if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) - { - - error->one(FLERR,"assertion failed"); - } - const ParticleBin & bin = bins[ibin+offset].p_array; - - for(ParticleBin::const_iterator pit = bin.begin(); pit != bin.end(); ++pit) { - const Particle & p = *pit; - double del[3]; - vectorSubtract3D(x, p.x, del); - const double rsq = vectorMag3DSquared(del); - const double radsum = radius + p.radius; - if (rsq <= radsum*radsum) return true; - } - } - - return false; -} - -#ifdef SUPERQUADRIC_ACTIVE_FLAG -//the same for superquadrics -bool RegionNeighborList::hasOverlap_superquadric(double * x, double radius, double *quaternion, double *shape) const { - int ibin = coord2bin(x); - - for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) { - const int offset = *it; - if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) - { - - error->one(FLERR,"assertion failed"); - } - const ParticleBin & bin = bins[ibin+offset]; - - double roundness[2] = {2.0, 2.0}; - Superquadric particle1(x, quaternion, shape, roundness); - for(ParticleBin::const_iterator pit = bin.begin(); pit != bin.end(); ++pit) { - const Particle & p = *pit; - double del[3]; - vectorSubtract3D(x, p.x, del); - const double rsq = vectorMag3DSquared(del); - const double radsum = radius + p.radius; - if(check_obb_flag) { - double x_copy[3], quaternion_copy[4], shape_copy[3]; - vectorCopy3D(p.x, x_copy); - vectorCopy4D(p.quaternion, quaternion_copy); - vectorCopy3D(p.shape, shape_copy); - Superquadric particle2(x_copy, quaternion_copy, shape_copy, roundness); - - if (rsq <= radsum*radsum and MathExtraLiggghtsSuperquadric::obb_intersect(&particle1, &particle2)) return true; - } else - if (rsq <= radsum*radsum) return true; - } - } - - return false; -} - -#endif -/** - * @brief Determine if the given particle overlaps with any particle in this neighbor list - * @param x position of particle to check - * @param radius radius of particle to check - * @param overlap_list list of overlaps, to be populated by this function - * @return true if particle has an overlap with a particle in this neighbor list, false otherwise - */ - -bool RegionNeighborList::hasOverlapWith(double * x, double radius, std::vector<int> &overlap_list) const { - int ibin = coord2binLocal(x); - - bool overlap = false; - - for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) { - const int offset = *it; - if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) - { - - error->one(FLERR,"assertion failed"); - } - const ParticleBin & bin = bins[ibin+offset].p_array; - - for(ParticleBin::const_iterator pit = bin.begin(); pit != bin.end(); ++pit) { - const Particle & p = *pit; - double del[3]; - vectorSubtract3D(x, p.x, del); - const double rsq = vectorMag3DSquared(del); - const double radsum = radius + p.radius; - if (rsq <= radsum*radsum) - { - overlap_list.push_back(p.index); - overlap = true; - } - } - } - - return overlap; -} - -/** - * @brief Insert a new particle into neighbor list - * @param x position in 3D - * @param radius particle radius - */ -void RegionNeighborList::insert(double * x, double radius,int index) { - int ibin = coord2binLocal(x); - if((ibin < 0) || ((size_t)(ibin) >= bins.size())) - { - - error->one(FLERR,"assertion failed"); - } - - bins[ibin].p_array.push_back(Particle(index,x, radius)); - ++ncount; -} - -#ifdef SUPERQUADRIC_ACTIVE_FLAG -//the same for superquadrics -void RegionNeighborList::insert_superquadric(double * x, double radius, double *quaternion, double *shape) { - int ibin = coord2bin(x); - if((ibin < 0) || ((size_t)(ibin) >= bins.size())) - { - - error->one(FLERR,"assertion failed"); - } - - bins[ibin].push_back(Particle(x, radius, quaternion, shape)); - ++ncount; -} -#endif - -/** - * @brief Clears neighbor list and brings it into initial state - */ -void RegionNeighborList::clear() { - bins.clear(); - stencil.clear(); - ncount = 0; -} - -/** - * @brief Returns the number of particles inserted into the neighbor list - * @return number of particles in neighbor list - */ -size_t RegionNeighborList::count() const { - return ncount; -} - -/** - * @brief Update the region bounding box - * - * This will update internal data structures to ensure they can handle the new - * region, which is defined by its bounding box. - * - * @param bb bounding box of region - * @param maxrad largest particle radius - * @return true if bounding box was set successfully, false bounding box could not - * be set and neighbor list is not usable - */ -bool RegionNeighborList::setBoundingBox(BoundingBox & bb, double maxrad, bool extend, bool failsafe) { - double extent[3]; - bb.getExtent(extent); - - if(extent[0] <= 0.0 || extent[1] <= 0.0 || extent[2] <= 0.0) { - // empty or invalid region - bins.clear(); - stencil.clear(); - return false; - } - - bb.getBoxBounds(bboxlo, bboxhi); - - // testing code - double binsize_optimal = 4*maxrad; - double binsizeinv = 1.0/binsize_optimal; - - // test for too many global bins in any dimension due to huge global domain or small maxrad - const int max_small_int = std::numeric_limits<int>::max(); - - if (extent[0]*binsizeinv > max_small_int || extent[1]*binsizeinv > max_small_int || - extent[2]*binsizeinv > max_small_int) - { - - if(failsafe) - { - binsizeinv = 1./ (vectorMax3D(extent) / 100.); - } - else - { - printf("ERROR: too many bins for this domain\n"); - return false; - } - } - - // create actual bins - nbinx = static_cast<int>(extent[0]*binsizeinv); - nbiny = static_cast<int>(extent[1]*binsizeinv); - nbinz = static_cast<int>(extent[2]*binsizeinv); - - if (nbinx == 0) nbinx = 1; - if (nbiny == 0) nbiny = 1; - if (nbinz == 0) nbinz = 1; - - binsizex = extent[0]/nbinx; - binsizey = extent[1]/nbiny; - binsizez = extent[2]/nbinz; - - bininvx = 1.0 / binsizex; - bininvy = 1.0 / binsizey; - bininvz = 1.0 / binsizez; - - // mbinlo/hi = lowest and highest global bins my ghost atoms could be in - // coord = lowest and highest values of coords for my ghost atoms - // static_cast(-1.5) = -1, so subract additional -1 - // add in SMALL for round-off safety - double bsubboxlo[3], bsubboxhi[3]; - bb.getBoxBounds(bsubboxlo, bsubboxhi); - - // list is extended for ghost atoms or - // the list covers just exactly the region - if (extend) - { - - double coord = bsubboxlo[0] - SMALL*extent[0]; - mbinxlo = static_cast<int> ((coord-bboxlo[0])*bininvx); - if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; - coord = bsubboxhi[0] + SMALL*extent[0]; - int mbinxhi = static_cast<int> ((coord-bboxlo[0])*bininvx); - - coord = bsubboxlo[1] - SMALL*extent[1]; - mbinylo = static_cast<int> ((coord-bboxlo[1])*bininvy); - if (coord < bboxlo[1]) mbinylo = mbinylo - 1; - coord = bsubboxhi[1] + SMALL*extent[1]; - int mbinyhi = static_cast<int> ((coord-bboxlo[1])*bininvy); - - coord = bsubboxlo[2] - SMALL*extent[2]; - mbinzlo = static_cast<int> ((coord-bboxlo[2])*bininvz); - if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; - coord = bsubboxhi[2] + SMALL*extent[2]; - int mbinzhi = static_cast<int> ((coord-bboxlo[2])*bininvz); - - // extend bins by 1 to insure stencil extent is included - - mbinxlo = mbinxlo - 1; - mbinxhi = mbinxhi + 1; - mbinylo = mbinylo - 1; - mbinyhi = mbinyhi + 1; - mbinzlo = mbinzlo - 1; - mbinzhi = mbinzhi + 1; - - mbinx = mbinxhi - mbinxlo + 1; - mbiny = mbinyhi - mbinylo + 1; - mbinz = mbinzhi - mbinzlo + 1; - -#ifdef LIGGGHTS_DEBUG - printf("setting insertion bounding box: [%g, %g] x [%g, %g] x [%g, %g]\n", bsubboxlo[0], bsubboxhi[0], bsubboxlo[1], bsubboxhi[1], bsubboxlo[2], bsubboxhi[2]); - printf("nbinx %d nbiny %d, nbinz %d\n",nbinx,nbiny,nbinz); - printf("mbinxlo: %d, mbinxhi: %d\n", mbinxlo, mbinxhi); - printf("mbinylo: %d, mbinyhi: %d\n", mbinylo, mbinyhi); - printf("mbinzlo: %d, mbinzhi: %d\n", mbinzlo, mbinzhi); - printf("mbinx %d mbiny %d, mbinz %d\n",mbinx,mbiny,mbinz); -#endif - - } - else - { - mbinxlo = mbinylo = mbinzlo = 0; - mbinx = nbinx; - mbiny = nbiny; - mbinz = nbinz; - -#ifdef LIGGGHTS_DEBUG - printf("setting reduced! insertion bounding box: [%g, %g] x [%g, %g] x [%g, %g]\n", bsubboxlo[0], bsubboxhi[0], bsubboxlo[1], bsubboxhi[1], bsubboxlo[2], bsubboxhi[2]); - printf("nbinx %d nbiny %d, nbinz %d\n",nbinx,nbiny,nbinz); - printf("mbinxlo: %d\n", mbinxlo); - printf("mbinylo: %d\n", mbinylo); - printf("mbinzlo: %d\n", mbinzlo); - printf("mbinx %d mbiny %d, mbinz %d\n",mbinx,mbiny,mbinz); -#endif - - } - - // allocate bins - bigint bbin = ((bigint) mbinx) * ((bigint) mbiny) * ((bigint) mbinz); - if (bbin > max_small_int) { - printf("ERROR: Too many neighbor bins\n"); - return false; - } - bins.resize(bbin); - // set cell center - for(std::vector<Bin>::iterator it = bins.begin(); it != bins.end(); ++it) - { - const int ibin = it - bins.begin(); - int itmp = ibin; - const int iz = ibin/(mbinx*mbiny); - itmp -= iz*mbinx*mbiny; - const int iy = itmp/mbinx; - itmp -= iy*mbinx; - const int ix = itmp; - it->center[0] = bsubboxlo[0] + binsizex*((double)(ix+mbinxlo)+0.5); - it->center[1] = bsubboxlo[1] + binsizey*((double)(iy+mbinylo)+0.5); - it->center[2] = bsubboxlo[2] + binsizez*((double)(iz+mbinzlo)+0.5); -//#ifdef LIGGGHTS_DEBUG -// printf("Bin (%d) with indizes: %d %d %d\n",ibin,ix,iy,iz); -// printf("Center of bin (%d): %g %g %g\n",ibin,it->center[0],it->center[1],it->center[2]); -//#endif - } - - // generate stencil which will look at all bins 27 bins - for (int k = -1; k <= 1; k++) - for (int j = -1; j <= 1; j++) - for (int i = -1; i <= 1; i++) - stencil.push_back(k*mbiny*mbinx + j*mbinx + i); - - bbox_set = true; - - return true; -} - -/** - * @brief Compute the closest distance between central bin (0,0,0) and bin (i,j,k) - * @param i bin coordinate along x-axis - * @param j bin coordinate along y-axis - * @param k bin coordinate along z-axis - * @return closest distance between central bin (0,0,0) and bin (i,j,k) - */ -double RegionNeighborList::bin_distance(int i, int j, int k) -{ - double delx,dely,delz; - - if (i > 0) delx = (i-1)*binsizex; - else if (i == 0) delx = 0.0; - else delx = (i+1)*binsizex; - - if (j > 0) dely = (j-1)*binsizey; - else if (j == 0) dely = 0.0; - else dely = (j+1)*binsizey; - - if (k > 0) delz = (k-1)*binsizez; - else if (k == 0) delz = 0.0; - else delz = (k+1)*binsizez; - - return (delx*delx + dely*dely + delz*delz); -} - -/** - * @brief Calc local bin index (m) of point x - * @param x point in 3D - * @return bin index of the given point x - */ -int RegionNeighborList::coord2binLocal(double *x) const -{ - int ix,iy,iz; - - if (x[0] >= bboxhi[0]) - ix = static_cast<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); - ix = std::min(ix,nbinx-1); - } else - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); - iy = std::min(iy,nbiny-1); - } else - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); - iz = std::min(iz,nbinz-1); - } else - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz) - 1; - - return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); -} - -/** - * @brief Calc global bin index (n) of point x - * @param x point in 3D - * @return bin index of the given point x - */ -int RegionNeighborList::coord2binGlobal(double *x) const -{ - - return RegionNeighborList::coord2binLocal(x); - /* - int ix,iy,iz; - - if (x[0] >= bboxhi[0]) - ix = static_cast<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); - ix = std::min(ix,nbinx-1); - } else - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); - iy = std::min(iy,nbiny-1); - } else - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); - iz = std::min(iz,nbinz-1); - } else - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz) - 1; - - return (iz)*nbiny*nbinx + (iy)*nbinx + (ix);*/ -} - -/** - * @brief Calc global bin index (n) of point x - * @param x point in 3D - * @return bin index of the given point x - */ - -bool RegionNeighborList::isInBoundingBox(double *pos) -{ - if(!boundingBoxSet()) - error->one(FLERR,"internal error: call before bbox is set"); - if - ( - pos[0] >= bboxlo[0] && pos[0] <= bboxhi[0] && - pos[1] >= bboxlo[1] && pos[1] <= bboxhi[1] && - pos[2] >= bboxlo[2] && pos[2] <= bboxhi[2] - ) return true; - return false; -} diff --git a/src/region_neighbor_list.h b/src/region_neighbor_list.h index d49ba5ff92b4df3276f5f1aaabf6e6b46e573c59..2d1cae4ce751f04f58f702ac866fdb00abcdefb1 100644 --- a/src/region_neighbor_list.h +++ b/src/region_neighbor_list.h @@ -51,58 +51,19 @@ #include "pointers.h" #include "bounding_box.h" #include "superquadric_flag.h" - -namespace LAMMPS_NS { - -/** - * @brief A small particle structure - */ -struct Particle { - int index; - double x[3]; - double radius; -#ifdef SUPERQUADRIC_ACTIVE_FLAG - double shape[3]; - double quaternion[4]; -#endif - - Particle(int i,double * pos, double rad) { - index = i; - LAMMPS_NS::vectorCopy3D(pos, x); - radius = rad; -#ifdef SUPERQUADRIC_ACTIVE_FLAG - quaternion[0] = 1.0; - quaternion[1] = quaternion[2] = quaternion[3] = 0.0; - shape[0] = shape[1] = shape[2] = radius; -#endif - } - Particle(double * pos, double rad) { - index = -1; - LAMMPS_NS::vectorCopy3D(pos, x); - radius = rad; -#ifdef SUPERQUADRIC_ACTIVE_FLAG - quaternion[0] = 1.0; - quaternion[1] = quaternion[2] = quaternion[3] = 0.0; - shape[0] = shape[1] = shape[2] = radius; -#endif - } +#include "region_neighbor_list_definitions.h" +#include "lmptype.h" +#include "mpi.h" +#include "bounding_box.h" +#include "error.h" +#include "region.h" +#include <limits> +#include <algorithm> #ifdef SUPERQUADRIC_ACTIVE_FLAG - Particle(double * pos, double rad, double *quaternion_, double *shape_) { - index = -1; - LAMMPS_NS::vectorCopy3D(pos, x); - radius = rad; - LAMMPS_NS::vectorCopy4D(quaternion_, quaternion); - LAMMPS_NS::vectorCopy3D(shape_, shape); - } +#include "math_extra_liggghts_superquadric.h" #endif -}; -typedef std::vector<Particle> ParticleBin; - -struct Bin { - double center[3]; - ParticleBin p_array; -}; +namespace LAMMPS_NS { /** * @brief A neighbor list of of a certain region @@ -114,13 +75,17 @@ struct Bin { * only allocates bins for his own sub-box */ +template<bool INTERPOLATE> class RegionNeighborList : protected LAMMPS_NS::Pointers { -public: + friend class FixAddforceSteadystate; + + public: RegionNeighborList(LAMMPS_NS::LAMMPS *lmp); + virtual ~RegionNeighborList() {} bool hasOverlap(double * x, double radius) const; - bool hasOverlapWith(double * x, double radius, std::vector<int> &overlap_list) const ; + bool hasOverlapWith(double * x, double radius, std::vector<int> &overlap_list) const; void insert(double * x, double radius,int index = -1); #ifdef SUPERQUADRIC_ACTIVE_FLAG bool hasOverlap_superquadric(double * x, double radius, double *quaternion, double *shape) const; @@ -129,25 +94,43 @@ public: #endif size_t count() const; - void clear(); + virtual void clear(); + virtual void reset(); + + inline void setBoundingBox_calc_interpolation_stencil(Bin<INTERPOLATE> &it,int ibin,int ix,int iy, int iz) const; + virtual bool setBoundingBox(LAMMPS_NS::BoundingBox & bb, double maxrad, bool extend = true, bool failsafe = false); - bool isInBoundingBox(double *pos); + virtual BoundingBox setBoundingBoxRegion(const Region ®ion, double maxrad, bool extend = true, bool failsafe = false); + + bool isInBoundingBox(double *pos) const; - bool boundingBoxSet() + inline void coord2bin_calc_interpolation_weights(double *x,int ibin,int ix,int iy, int iz,int &quadrant,double &wx,double &wy,double &wz) const; + + int coord2bin(double *x,int &quadrant,double &wx,double &wy,double &wz) const; + + inline int coord2bin(double *x) const + { int quadrant; double wx,wy,wz; return coord2bin(x,quadrant,wx,wy,wz); } + + bool boundingBoxSet() const {return bbox_set; } - int coord2binGlobal(double *x) const; - std::vector<Bin> getBins() const + std::vector<LAMMPS_NS::Bin<INTERPOLATE> > getBins() const {return bins; } double invBinVolume() const { return bininvx*bininvy*bininvz; } -protected: + inline int nbins() const + { return nbinx*nbiny*nbinz; } - std::vector<Bin> bins; // list of particle bins - std::vector<int> stencil; // stencil used to check bins for collisions - size_t ncount; // total number of particles in neighbor list + inline int mbins() const + { return mbinx*mbiny*mbinz; } + + protected: + + std::vector<Bin<INTERPOLATE> > bins;// list of particle bins + std::vector<int> stencil; // stencil used to check bins for collisions + size_t ncount; // total number of particles in neighbor list bool bbox_set; @@ -162,13 +145,17 @@ protected: double bininvx,bininvy,bininvz; // inverse of bin sizes double bin_distance(int i, int j, int k); - int coord2binLocal(double *x) const; #ifdef SUPERQUADRIC_ACTIVE_FLAG int check_obb_flag; #endif }; +/* +INCLUDE INLINE HEADER FILE +*/ +#include "region_neighbor_list_I.h" + } #endif // REGION_NEIGHBOR_LIST_H diff --git a/src/region_neighbor_list_I.h b/src/region_neighbor_list_I.h new file mode 100644 index 0000000000000000000000000000000000000000..0ee71ad75d4d7de2e70a02632d2da0995b93e8bd --- /dev/null +++ b/src/region_neighbor_list_I.h @@ -0,0 +1,688 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if not contributing author is listed, this file has been contributed + by the core developer) + + Richard Berger (JKU Linz) + Christoph Kloss (DCS Computing GmbH) + Alexander Podlozhnyuk (DCS Computing GmbH) + + Copyright 2014-2015 JKU Linz + Copyright 2015- DCS Computing GmbH +------------------------------------------------------------------------- */ + +static const double SMALL_REGION_NEIGHBOR_LIST = 1.0e-6; +static const double BIG_REGION_NEIGHBOR_LIST = 1.0e20; + +/** + * @brief Default constructor which will create an empty neighbor list + */ +template<bool INTERPOLATE> +RegionNeighborList<INTERPOLATE>::RegionNeighborList(LAMMPS *lmp) : + Pointers(lmp), + ncount(0), + bbox_set(false) +{ +} + +/** + * @brief Determine if the given particle overlaps with any particle in this neighbor list + * @param x position of particle to check + * @param radius radius of particle to check + * @return true if particle has an overlap with a particle in this neighbor list, false otherwise + */ +template<bool INTERPOLATE> +bool RegionNeighborList<INTERPOLATE>::hasOverlap(double * x, double radius) const +{ + int ibin = coord2bin(x); + + for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) + { + const int offset = *it; + if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) + { + + error->one(FLERR,"assertion failed"); + } + const std::vector<Particle<INTERPOLATE> > & plist = bins[ibin+offset].particles; + + for(typename std::vector<Particle<INTERPOLATE> >::const_iterator pit = plist.begin(); pit != plist.end(); ++pit) + { + const Particle<INTERPOLATE> & p = *pit; + double del[3]; + vectorSubtract3D(x, p.x, del); + const double rsq = vectorMag3DSquared(del); + const double radsum = radius + p.radius; + if (rsq <= radsum*radsum) return true; + } + } + + return false; +} + +#ifdef SUPERQUADRIC_ACTIVE_FLAG +//the same for superquadrics +bool RegionNeighborList<INTERPOLATE>::hasOverlap_superquadric(double * x, double radius, double *quaternion, double *shape) const { + int ibin = coord2bin(x); + + for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) { + const int offset = *it; + if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) + { + + error->one(FLERR,"assertion failed"); + } + const ParticleList & plist = bins[ibin+offset]; + + double roundness[2] = {2.0, 2.0}; + Superquadric particle1(x, quaternion, shape, roundness); + for(ParticleList::const_iterator pit = plist.begin(); pit != plist.end(); ++pit) { + const Particle & p = *pit; + double del[3]; + vectorSubtract3D(x, p.x, del); + const double rsq = vectorMag3DSquared(del); + const double radsum = radius + p.radius; + if(check_obb_flag) { + double x_copy[3], quaternion_copy[4], shape_copy[3]; + vectorCopy3D(p.x, x_copy); + vectorCopy4D(p.quaternion, quaternion_copy); + vectorCopy3D(p.shape, shape_copy); + Superquadric particle2(x_copy, quaternion_copy, shape_copy, roundness); + + if (rsq <= radsum*radsum and MathExtraLiggghtsSuperquadric::obb_intersect(&particle1, &particle2)) return true; + } else + if (rsq <= radsum*radsum) return true; + } + } + + return false; +} + +#endif +/** + * @brief Determine if the given particle overlaps with any particle in this neighbor list + * @param x position of particle to check + * @param radius radius of particle to check + * @param overlap_list list of overlaps, to be populated by this function + * @return true if particle has an overlap with a particle in this neighbor list, false otherwise + */ + +template<bool INTERPOLATE> +bool RegionNeighborList<INTERPOLATE>::hasOverlapWith(double * x, double radius, std::vector<int> &overlap_list) const +{ + int ibin = coord2bin(x); + + bool overlap = false; + + for(std::vector<int>::const_iterator it = stencil.begin(); it != stencil.end(); ++it) + { + const int offset = *it; + if((ibin+offset < 0) || ((size_t)(ibin+offset) >= bins.size())) + { + + error->one(FLERR,"assertion failed"); + } + const std::vector<Particle<INTERPOLATE> > & plist = bins[ibin+offset].particles; + + for(typename std::vector<Particle<INTERPOLATE> >::const_iterator pit = plist.begin(); pit != plist.end(); ++pit) + { + const Particle<INTERPOLATE> & p = *pit; + double del[3]; + vectorSubtract3D(x, p.x, del); + const double rsq = vectorMag3DSquared(del); + const double radsum = radius + p.radius; + if (rsq <= radsum*radsum) + { + overlap_list.push_back(p.index); + overlap = true; + } + } + } + + return overlap; +} + +/** + * @brief Insert a new particle into neighbor list + * @param x position in 3D + * @param radius particle radius + */ +template<bool INTERPOLATE> +void RegionNeighborList<INTERPOLATE>::insert(double * x, double radius,int index) +{ + int quadrant; + double wx,wy,wz; + int ibin = coord2bin(x,quadrant,wx,wy,wz); + if((ibin < 0) || ((size_t)(ibin) >= bins.size())) + { + + error->one(FLERR,"assertion failed"); + } + + bins[ibin].particles.push_back(Particle<INTERPOLATE>(index,x, radius,ibin,quadrant,wx,wy,wz)); + + ++ncount; +} + +#ifdef SUPERQUADRIC_ACTIVE_FLAG +//the same for superquadrics +void RegionNeighborList<INTERPOLATE>::insert_superquadric(double * x, double radius, double *quaternion, double *shape) { + int ibin = coord2bin(x); + if((ibin < 0) || ((size_t)(ibin) >= bins.size())) + { + + error->one(FLERR,"assertion failed"); + } + + bins[ibin].push_back(Particle(x, radius, quaternion, shape)); + ++ncount; +} +#endif + +/** + * @brief Reset neighbor list and brings it into initial state + */ +template<bool INTERPOLATE> +void RegionNeighborList<INTERPOLATE>::reset() +{ + // reset all the settings from setBoundaryBox + bins.clear(); + stencil.clear(); + bbox_set = false; + nbinx = nbiny = nbinz = 0; + binsizex = binsizey = binsizez = 0; + bininvx = bininvy = bininvz = 0; + mbinxlo = mbinylo = mbinzlo = 0; + mbinx = mbiny = mbinz = 0; + + // reset particle counter + ncount = 0; +} + +/** + * @brief Clear bins (remove all inserted particles) + */ +template<bool INTERPOLATE> +void RegionNeighborList<INTERPOLATE>::clear() +{ + for(typename std::vector<Bin<INTERPOLATE> >::iterator it = bins.begin(); it != bins.end(); ++it) + { + (*it).particles.clear(); + } + ncount = 0; +} + +/** + * @brief Returns the number of particles inserted into the neighbor list + * @return number of particles in neighbor list + */ + +template<bool INTERPOLATE> +size_t RegionNeighborList<INTERPOLATE>::count() const +{ + return ncount; +} + +/** + * @brief Set or Update the region bounding box + * + * This will update internal data structures to ensure they can handle the new + * region, which is defined by its bounding box. + * + * @param bb bounding box of region + * @param maxrad largest particle radius + * @param extend enable extending the box for ghost particles + * @param failsafe limit max. number of bins + * @return true if bounding box was set successfully, false bounding box could not + * be set and neighbor list is not usable + */ + +template<bool INTERPOLATE> +inline void RegionNeighborList<INTERPOLATE>::setBoundingBox_calc_interpolation_stencil(Bin<INTERPOLATE> &it,int ibin,int ix,int iy, int iz) const +{ + +} + +template<> +inline void RegionNeighborList<true>::setBoundingBox_calc_interpolation_stencil(Bin<true> &it,int ibin,int ix,int iy, int iz) const +{ + Stencil stencilTmp; + + it.stencils.clear(); + + int stencil_shift_up_quadrant = 0; + int stencil_shift_down_quadrant = 0; + int ii,jj,kk; + for(int iquad = 0; iquad < 8; iquad++) + { + + stencil_shift_up_quadrant = 0; + stencil_shift_down_quadrant = 0; + const int qx = (iquad & 1) >> 0; // 0 or 1 + const int qy = (iquad & 2) >> 1; // 0 or 1 + const int qz = (iquad & 4) >> 2; // 0 or 1 + + if(0 == ix && 0 == qx) + { + stencil_shift_up_quadrant |= 1; + ii = 1; + } + else if(ix == (mbinx-1) && 1 == qx) + { + stencil_shift_down_quadrant |= 1; + ii = -1; + } + else + ii = 0; + + if(0 == iy && 0 == qy) + { + stencil_shift_up_quadrant |= 2; + jj = 1; + } + else if(iy == (mbiny-1) && 1 == qy) + { + stencil_shift_down_quadrant |= 2; + jj = -1; + } + else + jj = 0; + + if(0 == iz && 0 == qz) + { + stencil_shift_up_quadrant |= 4; + kk = 1; + } + else if(iz == (mbinz-1) && 1 == qz) + { + stencil_shift_down_quadrant |= 4; + kk = -1; + } + else + kk = 0; + + // generate stencil which will look at 8 relevant bins - self + 7 quadrant neighs + // self can be located anywhere within these 8 bins + stencilTmp.clear(); + for (int k = -1+qz; k <= qz; k++) + { + for (int j = -1+qy; j <= qy; j++) + { + for (int i = -1+qx; i <= qx; i++) + { + stencilTmp.push_back((iz+k+kk)*mbiny*mbinx + (iy+j+jj)*mbinx + (ix+i+ii)); + + } + } + } + + it.stencils.push_back(stencilTmp); + + it.stencil_shift_up.push_back(stencil_shift_up_quadrant); + it.stencil_shift_down.push_back(stencil_shift_down_quadrant); + + } +} + +template<bool INTERPOLATE> +bool RegionNeighborList<INTERPOLATE>::setBoundingBox(BoundingBox & bb, double maxrad, bool extend, bool failsafe) +{ + double extent[3]; + bb.getExtent(extent); + + if(extent[0] <= 0.0 || extent[1] <= 0.0 || extent[2] <= 0.0) { + // empty or invalid region + bins.clear(); + stencil.clear(); + return false; + } + + bb.getBoxBounds(bboxlo, bboxhi); + + // testing code + double binsize_optimal = 4*maxrad; + double binsizeinv = 1.0/binsize_optimal; + + // test for too many global bins in any dimension due to huge global domain or small maxrad + const int max_small_int = std::numeric_limits<int>::max(); + + if (extent[0]*binsizeinv > 200 || extent[1]*binsizeinv > 200 || + extent[2]*binsizeinv > 200) + { + + if(failsafe) + { + binsizeinv = 1./ (vectorMax3D(extent) / 100.); + } + else + { + printf("ERROR: too many bins for this domain\n"); + return false; + } + } + + // create actual bins + nbinx = static_cast<int>(extent[0]*binsizeinv); + nbiny = static_cast<int>(extent[1]*binsizeinv); + nbinz = static_cast<int>(extent[2]*binsizeinv); + + if (nbinx == 0) nbinx = 1; + if (nbiny == 0) nbiny = 1; + if (nbinz == 0) nbinz = 1; + + binsizex = extent[0]/nbinx; + binsizey = extent[1]/nbiny; + binsizez = extent[2]/nbinz; + + bininvx = 1.0 / binsizex; + bininvy = 1.0 / binsizey; + bininvz = 1.0 / binsizez; + + // mbinlo/hi = lowest and highest global bins my ghost atoms could be in + // coord = lowest and highest values of coords for my ghost atoms + // static_cast(-1.5) = -1, so subract additional -1 + // add in SMALL for round-off safety + double bsubboxlo[3], bsubboxhi[3]; + bb.getBoxBounds(bsubboxlo, bsubboxhi); + + // list is extended for ghost atoms or + // the list covers just exactly the region + if (extend) + { + double coord = bsubboxlo[0] - SMALL_REGION_NEIGHBOR_LIST*extent[0]; + mbinxlo = static_cast<int> ((coord-bboxlo[0])*bininvx); + if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; + coord = bsubboxhi[0] + SMALL_REGION_NEIGHBOR_LIST*extent[0]; + int mbinxhi = static_cast<int> ((coord-bboxlo[0])*bininvx); + + coord = bsubboxlo[1] - SMALL_REGION_NEIGHBOR_LIST*extent[1]; + mbinylo = static_cast<int> ((coord-bboxlo[1])*bininvy); + if (coord < bboxlo[1]) mbinylo = mbinylo - 1; + coord = bsubboxhi[1] + SMALL_REGION_NEIGHBOR_LIST*extent[1]; + int mbinyhi = static_cast<int> ((coord-bboxlo[1])*bininvy); + + coord = bsubboxlo[2] - SMALL_REGION_NEIGHBOR_LIST*extent[2]; + mbinzlo = static_cast<int> ((coord-bboxlo[2])*bininvz); + if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; + coord = bsubboxhi[2] + SMALL_REGION_NEIGHBOR_LIST*extent[2]; + int mbinzhi = static_cast<int> ((coord-bboxlo[2])*bininvz); + + // extend bins by 1 to insure stencil extent is included + + mbinxlo = mbinxlo - 1; + mbinxhi = mbinxhi + 1; + mbinylo = mbinylo - 1; + mbinyhi = mbinyhi + 1; + mbinzlo = mbinzlo - 1; + mbinzhi = mbinzhi + 1; + + mbinx = mbinxhi - mbinxlo + 1; + mbiny = mbinyhi - mbinylo + 1; + mbinz = mbinzhi - mbinzlo + 1; + +#ifdef LIGGGHTS_DEBUG + printf("setting region neighlist bounding box: maxrad %g [%g, %g] x [%g, %g] x [%g, %g]\n", maxrad, bsubboxlo[0], bsubboxhi[0], bsubboxlo[1], bsubboxhi[1], bsubboxlo[2], bsubboxhi[2]); + printf("nbinx %d nbiny %d, nbinz %d\n",nbinx,nbiny,nbinz); + printf("mbinxlo: %d, mbinxhi: %d\n", mbinxlo, mbinxhi); + printf("mbinylo: %d, mbinyhi: %d\n", mbinylo, mbinyhi); + printf("mbinzlo: %d, mbinzhi: %d\n", mbinzlo, mbinzhi); + printf("mbinx %d mbiny %d, mbinz %d\n",mbinx,mbiny,mbinz); +#endif + + } + else + { + mbinxlo = mbinylo = mbinzlo = 0; + mbinx = nbinx; + mbiny = nbiny; + mbinz = nbinz; + +#ifdef LIGGGHTS_DEBUG + printf("setting reduced! insertion bounding box: [%g, %g] x [%g, %g] x [%g, %g]\n", bsubboxlo[0], bsubboxhi[0], bsubboxlo[1], bsubboxhi[1], bsubboxlo[2], bsubboxhi[2]); + printf("nbinx %d nbiny %d, nbinz %d\n",nbinx,nbiny,nbinz); + printf("mbinxlo: %d\n", mbinxlo); + printf("mbinylo: %d\n", mbinylo); + printf("mbinzlo: %d\n", mbinzlo); + printf("mbinx %d mbiny %d, mbinz %d\n",mbinx,mbiny,mbinz); +#endif + + } + + // allocate bins + bigint bbin = ((bigint) mbinx) * ((bigint) mbiny) * ((bigint) mbinz); + if (bbin > max_small_int) { + printf("ERROR: Too many neighbor bins\n"); + return false; + } + bins.resize(bbin); + + // set cell center and stencils for each bin + for(typename std::vector<Bin<INTERPOLATE> >::iterator it = bins.begin(); it != bins.end(); ++it) + { + const int ibin = it - bins.begin(); + int itmp = ibin; + const int iz = ibin/(mbinx*mbiny); + itmp -= iz*mbinx*mbiny; + const int iy = itmp/mbinx; + itmp -= iy*mbinx; + const int ix = itmp; + it->center[0] = bsubboxlo[0] + binsizex*((double)(ix+mbinxlo)+0.5); + it->center[1] = bsubboxlo[1] + binsizey*((double)(iy+mbinylo)+0.5); + it->center[2] = bsubboxlo[2] + binsizez*((double)(iz+mbinzlo)+0.5); + + setBoundingBox_calc_interpolation_stencil(*it,ibin,ix,iy,iz); + +//#ifdef LIGGGHTS_DEBUG +// printf("Bin (%d) with indizes: %d %d %d\n",ibin,ix,iy,iz); +// printf("Center of bin (%d): %g %g %g\n",ibin,it->center[0],it->center[1],it->center[2]); +//#endif + } + + // generate stencil which will look at all bins 27 bins + for (int k = -1; k <= 1; k++) + for (int j = -1; j <= 1; j++) + for (int i = -1; i <= 1; i++) + stencil.push_back(k*mbiny*mbinx + j*mbinx + i); + + bbox_set = true; + + return true; +} + +/** + * @brief Compute the closest distance between central bin (0,0,0) and bin (i,j,k) + * @param i bin coordinate along x-axis + * @param j bin coordinate along y-axis + * @param k bin coordinate along z-axis + * @return closest distance between central bin (0,0,0) and bin (i,j,k) + */ +template<bool INTERPOLATE> +double RegionNeighborList<INTERPOLATE>::bin_distance(int i, int j, int k) +{ + double delx,dely,delz; + + if (i > 0) delx = (i-1)*binsizex; + else if (i == 0) delx = 0.0; + else delx = (i+1)*binsizex; + + if (j > 0) dely = (j-1)*binsizey; + else if (j == 0) dely = 0.0; + else dely = (j+1)*binsizey; + + if (k > 0) delz = (k-1)*binsizez; + else if (k == 0) delz = 0.0; + else delz = (k+1)*binsizez; + + return (delx*delx + dely*dely + delz*delz); +} + +/** + * @brief Calc local bin index (m) of point x + * @param x point in 3D + * @return bin index of the given point x + */ + +template<bool INTERPOLATE> +inline void RegionNeighborList<INTERPOLATE>::coord2bin_calc_interpolation_weights(double *x,int ibin,int ix,int iy, int iz,int &quadrant,double &wx,double &wy,double &wz) const +{ + quadrant = 0; + wx = wy = wz = 0.; +} + +template<> +inline void RegionNeighborList<true>::coord2bin_calc_interpolation_weights(double *x,int ibin,int ix,int iy, int iz,int &quadrant,double &wx,double &wy,double &wz) const +{ + double dx = (((x[0]-bboxlo[0])*bininvx) - static_cast<int> ((x[0]-bboxlo[0])*bininvx));//*bininvx; + double dy = (((x[1]-bboxlo[1])*bininvy) - static_cast<int> ((x[1]-bboxlo[1])*bininvy));//*bininvy; + double dz = (((x[2]-bboxlo[2])*bininvz) - static_cast<int> ((x[2]-bboxlo[2])*bininvz));//*bininvz; + quadrant = (dx >= 0.5) * 1 + (dy >= 0.5) * 2 + (dz >= 0.5) * 4; + + if(dx >= 0.5) + wx = dx-0.5; + else + wx = 0.5+dx; + + if(dy >= 0.5) + wy = dy-0.5; + else + wy = 0.5+dy; + + if(dz >= 0.5) + wz = dz-0.5; + else + wz = 0.5+dz; + + int stencil_shift_up = bins[ibin].stencil_shift_up[quadrant]; + int stencil_shift_down = bins[ibin].stencil_shift_down[quadrant]; + if( 0 == stencil_shift_up && 0 == stencil_shift_down) + return; + + if(stencil_shift_down & 1) + wx = 1.; + else if(stencil_shift_up & 1) + wx = 0.; + + if(stencil_shift_down & 2) + wy = 1.; + else if(stencil_shift_up & 2) + wy = 0.; + + if(stencil_shift_down & 4) + wz = 1.; + else if(stencil_shift_up & 4) + wz = 0.; + +} + +template<bool INTERPOLATE> +int RegionNeighborList<INTERPOLATE>::coord2bin(double *x,int &quadrant,double &wx,double &wy,double &wz) const +{ + int ix,iy,iz; + + /*if(x[0] < bboxlo[0] || x[0] > bboxhi[0] || x[1] < bboxlo[1] || x[1] > bboxhi[1] || x[2] < bboxlo[2] || x[2] > bboxhi[2]) + return -1;*/ + + if (x[0] >= bboxhi[0]) + ix = static_cast<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); + ix = std::min(ix,nbinx-1); + } else + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); + iy = std::min(iy,nbiny-1); + } else + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); + iz = std::min(iz,nbinz-1); + } else + iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz) - 1; + + int ibin = (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + + if(ibin < 0 || ibin >= mbins()) + return -1; // ibin = -1 + coord2bin_calc_interpolation_weights(x,ibin,ix,iy,iz,quadrant,wx,wy,wz); + + return ibin; +} + +/** + * @brief Calc global bin index (n) of point x + * @param x point in 3D + * @return bin index of the given point x + */ + +template<bool INTERPOLATE> +bool RegionNeighborList<INTERPOLATE>::isInBoundingBox(double *pos) const +{ + if(!boundingBoxSet()) + error->one(FLERR,"internal error: call before bbox is set"); + if + ( + pos[0] >= bboxlo[0] && pos[0] <= bboxhi[0] && + pos[1] >= bboxlo[1] && pos[1] <= bboxhi[1] && + pos[2] >= bboxlo[2] && pos[2] <= bboxhi[2] + ) return true; + return false; +} + +/** + * @brief Set bounding box from region + * @param region Region used for creating the neighbor list + * @param maxrad largest particle radius + * @param extend enable extending the box for ghost particles + * @param failsafe limit max. number of bins + * @return BoundingBox the bounding box of the region + */ + +template<bool INTERPOLATE> +BoundingBox RegionNeighborList<INTERPOLATE>::setBoundingBoxRegion(const Region ®ion, double maxrad, bool extend, bool failsafe) +{ + // use region to determine and set bounding box + BoundingBox bb(region.extent_xlo, region.extent_xhi, region.extent_ylo, region.extent_yhi, region.extent_zlo, region.extent_zhi); + if (!setBoundingBox(bb, maxrad, extend, failsafe)) + error->one(FLERR,"internal error: could not set bounding box"); + + return bb; +} diff --git a/src/region_neighbor_list_definitions.h b/src/region_neighbor_list_definitions.h new file mode 100644 index 0000000000000000000000000000000000000000..5ed88988bfa232f9ecfa7ab2902c1f0770ade3ef --- /dev/null +++ b/src/region_neighbor_list_definitions.h @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if not contributing author is listed, this file has been contributed + by the core developer) + + Richard Berger (JKU Linz) + Christoph Kloss (DCS Computing GmbH) + Alexander Podlozhnyuk (DCS Computing GmbH) + + Copyright 2014-2015 JKU Linz + Copyright 2015- DCS Computing GmbH +------------------------------------------------------------------------- */ + +#ifndef REGION_NEIGHBOR_LIST_DEFINITIONS_H +#define REGION_NEIGHBOR_LIST_DEFINITIONS_H + +#include <vector> +#include "vector_liggghts.h" +#include "pointers.h" +#include "bounding_box.h" +#include "superquadric_flag.h" + +namespace LAMMPS_NS { + +class Region; + +/** + * @brief A small particle structure + */ + +template<bool INTERPOLATION> +class Particle +{}; + +template<> +class Particle<false /*interpolation*/> +{ + public: + int index; + double x[3]; + double radius; + +#ifdef SUPERQUADRIC_ACTIVE_FLAG + double shape[3]; + double quaternion[4]; +#endif + + Particle(int _i,double * _pos, double _rad, int,int,double,double,double) { + index = _i; + LAMMPS_NS::vectorCopy3D(_pos, x); + radius = _rad; + +#ifdef SUPERQUADRIC_ACTIVE_FLAG + quaternion[0] = 1.0; + quaternion[1] = quaternion[2] = quaternion[3] = 0.0; + shape[0] = shape[1] = shape[2] = radius; +#endif + } + +#ifdef SUPERQUADRIC_ACTIVE_FLAG + Particle(double * pos, double rad, double *quaternion_, double *shape_) { + index = -1; + LAMMPS_NS::vectorCopy3D(pos, x); + radius = rad; + LAMMPS_NS::vectorCopy4D(quaternion_, quaternion); + LAMMPS_NS::vectorCopy3D(shape_, shape); + } +#endif +}; + +template<> +class Particle<true /*interpolation*/> +{ + public: + int index; + double x[3]; + double radius; + + int ibin; + int quadrant_bitfield; + double wx, wy, wz; + +#ifdef SUPERQUADRIC_ACTIVE_FLAG + double shape[3]; + double quaternion[4]; +#endif + + Particle(int _i,double * _pos, double _rad,int _ibin,int _quadrant,double _wx = -1.,double _wy = -1.,double _wz = -1.) { + index = _i; + LAMMPS_NS::vectorCopy3D(_pos, x); + radius = _rad; + ibin = _ibin; + quadrant_bitfield = _quadrant; + wx = _wx; + wy = _wy; + wz = _wz; +#ifdef SUPERQUADRIC_ACTIVE_FLAG + quaternion[0] = 1.0; + quaternion[1] = quaternion[2] = quaternion[3] = 0.0; + shape[0] = shape[1] = shape[2] = radius; +#endif + } + +#ifdef SUPERQUADRIC_ACTIVE_FLAG + Particle(double * pos, double rad, double *quaternion_, double *shape_) { + index = -1; + LAMMPS_NS::vectorCopy3D(pos, x); + radius = rad; + LAMMPS_NS::vectorCopy4D(quaternion_, quaternion); + LAMMPS_NS::vectorCopy3D(shape_, shape); + TODO_QUADRANT,WEIGHTS + } +#endif +}; + +/** + * @brief typedefs + */ + +typedef std::vector<Particle<true> > ParticleListInterpolate; +typedef std::vector<Particle<false> > ParticleListNoInterpolate; + +typedef std::vector<int> Stencil; + +const static bool interpolate_yes = true; +const static bool interpolate_no = false; + +/** + * @brief Bin class + * + * Defines data structure for binning + * Variants with and without interpolation. Interpolation + * variant stores lists with offsets + */ + +template<bool INTERPOLATION> +class Bin +{}; + +template<> +class Bin<false> +{ + public: + double center[3]; + + ParticleListNoInterpolate particles; +}; + +template<> +class Bin<true> +{ + public: + double center[3]; + + ParticleListInterpolate particles; + + std::vector<Stencil> stencils; + + std::vector<int> stencil_shift_down; + + std::vector<int> stencil_shift_up; +}; + +} + +#endif diff --git a/src/rerun.cpp b/src/rerun.cpp deleted file mode 100644 index 3eac4bed001ab213d7782b89d1d4ed6d4de25f62..0000000000000000000000000000000000000000 --- a/src/rerun.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* ---------------------------------------------------------------------- - This is the - - ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ - ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ - ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ - ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ - ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ - ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® - - DEM simulation engine, released by - DCS Computing Gmbh, Linz, Austria - http://www.dcs-computing.com, office@dcs-computing.com - - LIGGGHTS® is part of CFDEM®project: - http://www.liggghts.com | http://www.cfdem.com - - Core developer and main author: - Christoph Kloss, christoph.kloss@dcs-computing.com - - LIGGGHTS® is open-source, distributed under the terms of the GNU Public - License, version 2 or later. It is distributed in the hope that it will - be useful, but WITHOUT ANY WARRANTY; without even the implied warranty - of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have - received a copy of the GNU General Public License along with LIGGGHTS®. - If not, see http://www.gnu.org/licenses . See also top-level README - and LICENSE files. - - LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, - the producer of the LIGGGHTS® software and the CFDEM®coupling software - See http://www.cfdem.com/terms-trademark-policy for details. - -------------------------------------------------------------------------- - Contributing author and copyright for this file: - This file is from LAMMPS - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. -------------------------------------------------------------------------- */ - -#include "lmptype.h" -#include "stdlib.h" -#include "string.h" -#include "rerun.h" -#include "read_dump.h" -#include "domain.h" -#include "update.h" -#include "integrate.h" -#include "modify.h" -#include "output.h" -#include "finish.h" -#include "timer.h" -#include "error.h" -#include "force.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -Rerun::Rerun(LAMMPS *lmp) : Pointers(lmp) {} - -/* ---------------------------------------------------------------------- */ - -void Rerun::command(int narg, char **arg) -{ - if (domain->box_exist == 0) - error->all(FLERR,"Rerun command before simulation box is defined"); - - if (narg < 2) error->all(FLERR,"Illegal rerun command"); - - // list of dump files = args until a keyword - - int iarg = 0; - while (iarg < narg) { - if (strcmp(arg[iarg],"first") == 0) break; - if (strcmp(arg[iarg],"last") == 0) break; - if (strcmp(arg[iarg],"every") == 0) break; - if (strcmp(arg[iarg],"skip") == 0) break; - if (strcmp(arg[iarg],"start") == 0) break; - if (strcmp(arg[iarg],"stop") == 0) break; - if (strcmp(arg[iarg],"dump") == 0) break; - iarg++; - } - int nfile = iarg; - if (nfile == 0 || nfile == narg) error->all(FLERR,"Illegal rerun command"); - - // parse optional args up until "dump" - // user MAXBIGINT -1 so Output can add 1 to it and still be a big int - - bigint first = 0; - bigint last = MAXBIGINT - 1; - int nevery = 0; - int nskip = 1; - int startflag = 0; - int stopflag = 0; - bigint start=0,stop=0; - - while (iarg < narg) { - if (strcmp(arg[iarg],"first") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - first = ATOBIGINT(arg[iarg+1]); - if (first < 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"last") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - last = ATOBIGINT(arg[iarg+1]); - if (last < 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"every") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - nevery = force->inumeric(FLERR,arg[iarg+1]); - if (nevery < 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"skip") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - nskip = force->inumeric(FLERR,arg[iarg+1]); - if (nskip <= 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"start") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - startflag = 1; - start = ATOBIGINT(arg[iarg+1]); - if (start < 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"stop") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); - stopflag = 1; - stop = ATOBIGINT(arg[iarg+1]); - if (stop < 0) error->all(FLERR,"Illegal rerun command"); - iarg += 2; - } else if (strcmp(arg[iarg],"dump") == 0) { - break; - } else error->all(FLERR,"Illegal rerun command"); - } - - int nremain = narg - iarg - 1; - if (nremain <= 0) error->all(FLERR,"Illegal rerun command"); - if (first > last) error->all(FLERR,"Illegal rerun command"); - if (startflag && stopflag && start > stop) - error->all(FLERR,"Illegal rerun command"); - - // pass list of filenames to ReadDump - // along with post-"dump" args and post-"format" args - - ReadDump *rd = new ReadDump(lmp); - - rd->store_files(nfile,arg); - if (nremain) - nremain = rd->fields_and_keywords(nremain,&arg[narg-nremain]); - else nremain = rd->fields_and_keywords(0,NULL); - if (nremain) rd->setup_reader(nremain,&arg[narg-nremain]); - else rd->setup_reader(0,NULL); - - // perform the psuedo run - // invoke lmp->init() only once - // read all relevant snapshots - // uset setup_minimal() since atoms are already owned by correct procs - // addstep_compute_all() insures energy/virial computed on every snapshot - - update->whichflag = 1; - - if (startflag) update->beginstep = update->firststep = start; - else update->beginstep = update->firststep = first; - if (stopflag) update->endstep = update->laststep = stop; - else update->endstep = update->laststep = last; - - int firstflag = 1; - int ndump = 0; - - lmp->init(); - - timer->init(); - timer->barrier_start(TIME_LOOP); - - bigint ntimestep = rd->seek(first,0); - if (ntimestep < 0) - error->all(FLERR,"Rerun dump file does not contain requested snapshot"); - - while (1) { - ndump++; - rd->header(firstflag); - update->reset_timestep(ntimestep); - rd->atoms(); - - modify->init(); - update->integrate->setup_minimal(1); - modify->end_of_step(); - if (firstflag) output->setup(); - else if (output->next) output->write(ntimestep); - - firstflag = 0; - ntimestep = rd->next(ntimestep,last,nevery,nskip); - if (ntimestep < 0) break; - } - - // insure thermo output on last dump timestep - - output->next_thermo = update->ntimestep; - output->write(update->ntimestep); - - timer->barrier_stop(TIME_LOOP); - - update->integrate->cleanup(); - - // set update->nsteps to ndump for Finish stats to print - - update->nsteps = ndump; - - Finish finish(lmp); - finish.end(1); - - update->whichflag = 0; - update->firststep = update->laststep = 0; - update->beginstep = update->endstep = 0; - - // clean-up - - delete rd; -} diff --git a/src/rolling_model_epsd.h b/src/rolling_model_epsd.h index f95e9912365231001b7b3c3904ad6c7e1fbe353c..d99848aaa68c295106a9b81fc23d7d302ad74ee4 100644 --- a/src/rolling_model_epsd.h +++ b/src/rolling_model_epsd.h @@ -33,8 +33,10 @@ ------------------------------------------------------------------------- Contributing author and copyright for this file: - Andreas Aigner (JKU Linz) + Andreas Aigner (DCS Computing GmbH, Linz) Christoph Kloss (DCS Computing GmbH, Linz) + Alexander Podlodhnyuk (DCS Computing GmbH, Linz) + Andreas Aigner (JKU Linz) Christoph Kloss (JKU Linz) Richard Berger (JKU Linz) @@ -86,7 +88,7 @@ namespace ContactModels error->cg(FLERR,"rolling model epsd"); } - void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces) + void surfacesIntersect(SurfacesIntersectData & sidata, ForceData & i_forces, ForceData & j_forces) { double r_torque[3]; vectorZeroize3D(r_torque); @@ -120,13 +122,13 @@ namespace ContactModels const double Ix = sidata.inertia_i[0]; const double Iy = sidata.inertia_i[1]; const double Iz = sidata.inertia_i[2]; - double inertia_tensor[3][3]; - double inertia_tensor_local[3][3] = { {Ix, 0.0, 0.0}, - {0.0, Iy, 0.0}, - {0.0, 0.0, Iz} }; + double inertia_tensor[9]; + double inertia_tensor_local[9] = { Ix, 0.0, 0.0, + 0.0, Iy, 0.0, + 0.0, 0.0, Iz }; MathExtraLiggghtsSuperquadric::tensor_quat_rotate(inertia_tensor_local, sidata.quat_i, inertia_tensor); double temp[3]; - MathExtra::matvec(inertia_tensor, er, temp); + MathExtraLiggghtsSuperquadric::matvec(inertia_tensor, er, temp); double Ii = MathExtra::dot3(temp, er); r_inertia = Ii + sidata.mi*rii*rii; } @@ -174,20 +176,20 @@ namespace ContactModels const double Iy_j = sidata.inertia_j[1]; const double Iz_j = sidata.inertia_j[2]; - double inertia_tensor_i[3][3]; - double inertia_tensor_local_i[3][3] = { {Ix_i, 0.0, 0.0}, - {0.0, Iy_i, 0.0}, - {0.0, 0.0, Iz_i} }; - double inertia_tensor_j[3][3]; - double inertia_tensor_local_j[3][3] = { {Ix_j, 0.0, 0.0}, - {0.0, Iy_j, 0.0}, - {0.0, 0.0, Iz_j} }; + double inertia_tensor_i[9]; + double inertia_tensor_local_i[9] = { Ix_i, 0.0, 0.0, + 0.0, Iy_i, 0.0, + 0.0, 0.0, Iz_i }; + double inertia_tensor_j[9]; + double inertia_tensor_local_j[9] = { Ix_j, 0.0, 0.0, + 0.0, Iy_j, 0.0, + 0.0, 0.0, Iz_j }; MathExtraLiggghtsSuperquadric::tensor_quat_rotate(inertia_tensor_local_i, sidata.quat_i, inertia_tensor_i); MathExtraLiggghtsSuperquadric::tensor_quat_rotate(inertia_tensor_local_j, sidata.quat_j, inertia_tensor_j); double temp[3]; - MathExtra::matvec(inertia_tensor_i, er, temp); + MathExtraLiggghtsSuperquadric::matvec(inertia_tensor_i, er, temp); double Ii = MathExtra::dot3(temp, er); - MathExtra::matvec(inertia_tensor_j, er, temp); + MathExtraLiggghtsSuperquadric::matvec(inertia_tensor_j, er, temp); double Ij = MathExtra::dot3(temp, er); r_inertia_red_i = Ii + sidata.mi*rii*rii; // r_inertia_red_j = Ij + sidata.mj*rjj*rjj; diff --git a/src/scalar_container.h b/src/scalar_container.h index c7abb336f22bacccd351f1e21113ce0113e4123a..eb6df9a5c792a3918c8038e1b12e1573b19d782c 100644 --- a/src/scalar_container.h +++ b/src/scalar_container.h @@ -125,8 +125,8 @@ namespace LAMMPS_NS { if(this->numElem_ == this->maxElem_) { - grow<T>(this->arr_,this->maxElem_+GROW,1,1); - this->maxElem_ += GROW; + grow<T>(this->arr_,this->maxElem_+GROW_CONTAINER(),1,1); + this->maxElem_ += GROW_CONTAINER(); } this->arr_[this->numElem_][0][0] = elem; this->numElem_++; diff --git a/src/settings.h b/src/settings.h index b1e289516ed3dbd3167b48a051613c00e0d7746b..0b6a450647a1251a39cd0959b9bf9a3b9a675244 100644 --- a/src/settings.h +++ b/src/settings.h @@ -46,6 +46,7 @@ #include <set> #include <map> #include <sstream> +#include <stdlib.h> using namespace LAMMPS_NS; using namespace std; diff --git a/src/string_liggghts.h b/src/string_liggghts.h new file mode 100644 index 0000000000000000000000000000000000000000..208b69ade5564890e0e0f706209d075ce4398b3a --- /dev/null +++ b/src/string_liggghts.h @@ -0,0 +1,72 @@ +/* ---------------------------------------------------------------------- + This is the + + ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ + ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ + ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ + ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ + ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® + + DEM simulation engine, released by + DCS Computing Gmbh, Linz, Austria + http://www.dcs-computing.com, office@dcs-computing.com + + LIGGGHTS® is part of CFDEM®project: + http://www.liggghts.com | http://www.cfdem.com + + Core developer and main author: + Christoph Kloss, christoph.kloss@dcs-computing.com + + LIGGGHTS® is open-source, distributed under the terms of the GNU Public + License, version 2 or later. It is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have + received a copy of the GNU General Public License along with LIGGGHTS®. + If not, see http://www.gnu.org/licenses . See also top-level README + and LICENSE files. + + LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, + the producer of the LIGGGHTS® software and the CFDEM®coupling software + See http://www.cfdem.com/terms-trademark-policy for details. + +------------------------------------------------------------------------- + Contributing author and copyright for this file: + (if not contributing author is listed, this file has been contributed + by the core developer) + + Copyright 2016- DCS Computing GmbH, Linz +------------------------------------------------------------------------- */ + +#ifndef LMP_STRING_LIGGGHTS_H +#define LMP_STRING_LIGGGHTS_H + +namespace LAMMPS_NS { + +//================================================ +//SOME VERY SIMPLE VECTOR OPERATIONS +//================================================ + +/** + * @brief str_ends_with + * @param str + * @param suffix + * @return + */ +inline bool strEndWith(const char * str, const char * suffix) { + + if( str == NULL || suffix == NULL ) + return false; + + const size_t str_len = strlen(str); + const size_t suffix_len = strlen(suffix); + + if(suffix_len > str_len) + return false; + + return strncmp( str + str_len - suffix_len, suffix, suffix_len ) == 0; +} + +} // LAMMPS_NS + +#endif diff --git a/src/style_command.h b/src/style_command.h index 8adca8656f85509b747d49fd98913eb3da656443..b281216bb7d79d259482c409d51d83ab54fa223e 100644 --- a/src/style_command.h +++ b/src/style_command.h @@ -9,7 +9,6 @@ #include "read_dump.h" #include "read_restart.h" #include "replicate.h" -#include "rerun.h" #include "rotate.h" #include "run.h" #include "set.h" diff --git a/src/style_dump.h b/src/style_dump.h index 8f726c3aeea936113efd7dc2db48060b572d0696..612dbe2965f8d132673866b313da06f53aee32d2 100644 --- a/src/style_dump.h +++ b/src/style_dump.h @@ -4,6 +4,7 @@ #include "dump_decomposition_vtk.h" #include "dump_euler_vtk.h" #include "dump_image.h" +#include "dump_local_gran_vtk.h" #include "dump_local.h" #include "dump_mesh_stl.h" #include "dump_mesh_vtk.h" diff --git a/src/style_fix.h b/src/style_fix.h index 4d29068c3f31d854c0236e93eb0ed19a15326831..323e0112bb32d2513f721ed93668430fc836c073 100644 --- a/src/style_fix.h +++ b/src/style_fix.h @@ -7,9 +7,11 @@ #include "fix_ave_histo.h" #include "fix_ave_spatial.h" #include "fix_ave_time.h" +#include "fix_base_liggghts.h" #include "fix_box_relax.h" #include "fix_buoyancy.h" #include "fix_cfd_coupling_convection.h" +#include "fix_cfd_coupling_convection_impl.h" #include "fix_cfd_coupling_convection_species.h" #include "fix_cfd_coupling_force.h" #include "fix_cfd_coupling_force_implicit.h" @@ -57,6 +59,7 @@ #include "fix_planeforce.h" #include "fix_print.h" #include "fix_property_atom.h" +#include "fix_property_atom_timetracer.h" #include "fix_property_atom_tracer.h" #include "fix_property_atom_tracer_stream.h" #include "fix_property_global.h" diff --git a/src/surface_mesh.h b/src/surface_mesh.h index 7026d36103bb0ec7d4f7a006dedae836625fc015..6512fd76bacf971ceae509a02ee2f0743e30a660 100644 --- a/src/surface_mesh.h +++ b/src/surface_mesh.h @@ -55,6 +55,7 @@ #include "mpi_liggghts.h" #include "comm.h" #include <cmath> +#include <math.h> #include "math_extra_liggghts.h" #define EPSILON_CURVATURE 0.00001 @@ -162,6 +163,8 @@ class SurfaceMesh : public TrackingMesh<NUM_NODES> int *idListVisited,int &nIdListHasNode,int *idListHasNode, double **edgeList,double **edgeEndPoint,bool &anyActiveEdge); + #include "surface_mesh_feature_remove.h" + // (re) calc properties void calcSurfPropertiesOfNewElement(); void calcSurfPropertiesOfElement(int n); @@ -241,11 +244,14 @@ class SurfaceMesh : public TrackingMesh<NUM_NODES> // for overlap check on element insertion - RegionNeighborList &neighList_; + RegionNeighborList<interpolate_no> &neighList_; }; // ************************************* #include "surface_mesh_I.h" + +#include "surface_mesh_feature_remove_I.h" + // ************************************* } /* LAMMPS_NS */ diff --git a/src/surface_mesh_I.h b/src/surface_mesh_I.h index 98d6189d2160772f43e5d9d00e911c665bc119e9..b6c6aea6c31952a898349317dddb92d6dc47d24a 100644 --- a/src/surface_mesh_I.h +++ b/src/surface_mesh_I.h @@ -60,7 +60,7 @@ SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::SurfaceMesh(LAMMPS *lmp) minAngle_softLimit_(cos(0.5*M_PI/180.)), - minAngle_hardLimit_(0.999995), + minAngle_hardLimit_(0.9999995), // TODO should keep areaMeshSubdomain up-to-date more often for insertion faces areaMesh_ (*this->prop().template addGlobalProperty < ScalarContainer<double> > ("areaMesh", "comm_none","frame_trans_rot_invariant","restart_no",2)), @@ -81,7 +81,7 @@ SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::SurfaceMesh(LAMMPS *lmp) hasNonCoplanarSharedNode_(*this->prop().template addElementProperty< VectorContainer<bool,NUM_NODES> >("hasNonCoplanarSharedNode","comm_exchange_borders","frame_invariant", "restart_no")), edgeActive_ (*this->prop().template addElementProperty< VectorContainer<bool,NUM_NODES> > ("edgeActive", "comm_exchange_borders","frame_invariant","restart_no")), cornerActive_ (*this->prop().template addElementProperty< VectorContainer<bool,NUM_NODES> > ("cornerActive", "comm_exchange_borders","frame_invariant","restart_no")), - neighList_(*new RegionNeighborList(lmp)) + neighList_(*new RegionNeighborList<interpolate_no>(lmp)) { areaMesh_.add(0.); @@ -313,7 +313,7 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::calcSurfPropertiesOfNewElement() calcObtuseAngleIndex(n,i,dot); if(-dot > minAngle_softLimit_) hasSmallAngleSoftLimit = true; - if(-dot > minAngle_hardLimit_) + if(-dot >= minAngle_hardLimit_) hasSmallAngleHardLimit = true; } @@ -374,7 +374,15 @@ template<int NUM_NODES, int NUM_NEIGH_MAX> void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::calcSurfaceNorm(int nElem, double *surfNorm) { vectorCross3D(edgeVec(nElem)[0],edgeVec(nElem)[1],surfNorm); - vectorScalarDiv3D(surfNorm, vectorMag3D(surfNorm)); + + if(vectorMag3D(surfNorm) <1e-15) + { + surfNorm[0] = - edgeVec(nElem)[0][1]; + surfNorm[1] = edgeVec(nElem)[0][0]; + surfNorm[2] = edgeVec(nElem)[0][2]; + } + else + vectorScalarDiv3D(surfNorm, vectorMag3D(surfNorm)); } template<int NUM_NODES, int NUM_NEIGH_MAX> @@ -438,14 +446,22 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::buildNeighbours() this->domain->boxlo[2], this->domain->boxhi[2]); neighList_.clear(); + + double rBound_max = this->rBound_.max(); + double binsize_factor = rBound_max ; - if(nall > 0 && neighList_.setBoundingBox(bb, this->rBound_.max() /*max bounding radius*/, true)) + if(nall > 100000 && binsize_factor > cbrt(bb.getVolume())/(4*20.)) + { + binsize_factor = cbrt(bb.getVolume())/(4*20.); + } + + if(nall > 0 && neighList_.setBoundingBox(bb, binsize_factor, true, true)) { std::vector<int> overlaps; for (int i = 0; i < nall; ++i) { - + overlaps.clear(); neighList_.hasOverlapWith(this->center_(i), this->rBound_(i),overlaps); @@ -467,8 +483,6 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::buildNeighbours() else if(nall > 0) this->error->one(FLERR,"Mesh error: bounding box for neigh topology not set sucessfully"); - fflush(MultiNodeMesh<NUM_NODES>::elementExclusionList()); - int *idListVisited = new int[nall]; int *idListHasNode = new int[nall]; double **edgeList,**edgeEndPoint; @@ -482,14 +496,19 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::buildNeighbours() handleCorner(i,iNode,idListVisited,idListHasNode,edgeList,edgeEndPoint); } + handleExclusion(idListVisited); + delete []idListVisited; delete []idListHasNode; this->memory->destroy(edgeList); this->memory->destroy(edgeEndPoint); + fflush(MultiNodeMesh<NUM_NODES>::elementExclusionList()); + // correct edge and corner activation/deactivation in parallel parallelCorrection(); + } /* ---------------------------------------------------------------------- @@ -514,7 +533,15 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::qualityCheck() neighList_.clear(); - if(nall > 0 && neighList_.setBoundingBox(bb, this->rBound_.max() /*max bounding radius*/, true)) + double rBound_max = this->rBound_.max(); + double binsize_factor = rBound_max; + + if(nall > 100000 && binsize_factor > cbrt(bb.getVolume())/(4*20.)) + { + binsize_factor = cbrt(bb.getVolume())/(4*20.); + } + + if(nall > 0 && neighList_.setBoundingBox(bb, binsize_factor, true,true)) { std::vector<int> overlaps; @@ -535,7 +562,10 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::qualityCheck() fprintf(this->screen,"ERROR: Mesh %s: elements %d and %d (lines %d and %d) are duplicate\n", this->mesh_id_,TrackingMesh<NUM_NODES>::id(i),TrackingMesh<NUM_NODES>::id(j), TrackingMesh<NUM_NODES>::lineNo(i),TrackingMesh<NUM_NODES>::lineNo(j)); - if(!this->removeDuplicates()) + + if(MultiNodeMesh<NUM_NODES>::elementExclusionList()) + fprintf(MultiNodeMesh<NUM_NODES>::elementExclusionList(),"%d\n",TrackingMesh<NUM_NODES>::lineNo(j)); + else if(!this->removeDuplicates()) this->error->one(FLERR,"Fix mesh: Bad mesh, cannot continue. You can try re-running with 'heal auto_remove_duplicates'"); else this->error->one(FLERR,"Fix mesh: Bad mesh, cannot continue. The mesh probably reached the precision you defined. " @@ -549,6 +579,8 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::qualityCheck() else if(nall > 0) this->error->one(FLERR,"Mesh error: bounding box for neigh topology not set sucessfully"); + fflush(MultiNodeMesh<NUM_NODES>::elementExclusionList()); + for(int i = 0; i < nlocal; i++) { for(int iNode = 0; iNode < NUM_NODES; iNode++) @@ -589,7 +621,6 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::qualityCheck() fprintf(this->screen,"Mesh %s: element %d (line %d) has a really unreasonably high aspect ratio (hard limit: smallest angle must be > %f °) \n", this->mesh_id_,TrackingMesh<NUM_NODES>::id(i),TrackingMesh<NUM_NODES>::lineNo(i),this->angleHardLimit()); nBelowAngle_hardLimit++; - } } } @@ -868,22 +899,29 @@ void SurfaceMesh<NUM_NODES,NUM_NEIGH_MAX>::handleSharedEdge(int iSrf, int iEdge, if(neighflag) { - if(nNeighs_(iSrf) == NUM_NEIGH_MAX || nNeighs_(jSrf) == NUM_NEIGH_MAX) + if(nNeighs_(iSrf) == NUM_NEIGH_MAX) + { + nTooManyNeighs_++; + if(TrackingMesh<NUM_NODES>::verbose()) + fprintf(this->screen,"Mesh %s: element id %d (line %d) has %d neighs, but only %d expected\n", + this->mesh_id_,TrackingMesh<NUM_NODES>::id(iSrf),TrackingMesh<NUM_NODES>::lineNo(iSrf),nNeighs_(iSrf)+1,NUM_NEIGH_MAX); + if(MultiNodeMesh<NUM_NODES>::elementExclusionList()) + { + + fprintf(MultiNodeMesh<NUM_NODES>::elementExclusionList(),"%d\n",TrackingMesh<NUM_NODES>::lineNo(iSrf)); + } + + } + if(nNeighs_(jSrf) == NUM_NEIGH_MAX) { - int ii; - if(nNeighs_(iSrf) == NUM_NEIGH_MAX) - ii = iSrf; - else - ii = jSrf; - nTooManyNeighs_++; if(TrackingMesh<NUM_NODES>::verbose()) fprintf(this->screen,"Mesh %s: element id %d (line %d) has %d neighs, but only %d expected\n", - this->mesh_id_,TrackingMesh<NUM_NODES>::id(ii),TrackingMesh<NUM_NODES>::lineNo(ii),nNeighs_(ii)+1,NUM_NEIGH_MAX); + this->mesh_id_,TrackingMesh<NUM_NODES>::id(jSrf),TrackingMesh<NUM_NODES>::lineNo(jSrf),nNeighs_(jSrf)+1,NUM_NEIGH_MAX); if(MultiNodeMesh<NUM_NODES>::elementExclusionList()) { - fprintf(MultiNodeMesh<NUM_NODES>::elementExclusionList(),"%d\n",TrackingMesh<NUM_NODES>::lineNo(ii)); + fprintf(MultiNodeMesh<NUM_NODES>::elementExclusionList(),"%d\n",TrackingMesh<NUM_NODES>::lineNo(jSrf)); } } diff --git a/src/surface_mesh_feature_remove.h b/src/surface_mesh_feature_remove.h new file mode 100644 index 0000000000000000000000000000000000000000..fad7c3e108ea12219bad56b50ae68129c88c4a6e --- /dev/null +++ b/src/surface_mesh_feature_remove.h @@ -0,0 +1 @@ +void handleExclusion(int *) {this->error->one(FLERR,"surface mesh feature remove not available in this version");} diff --git a/src/surface_mesh_feature_remove_I.h b/src/surface_mesh_feature_remove_I.h new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/src/surface_mesh_feature_remove_I.h @@ -0,0 +1 @@ + diff --git a/src/tangential_model_history.h b/src/tangential_model_history.h index 927ed00e273d184af9a0a5ab441e9e47c3d86ce3..cfdf2942e418e9109db8e7829814e771f61f4c95 100644 --- a/src/tangential_model_history.h +++ b/src/tangential_model_history.h @@ -238,6 +238,8 @@ namespace ContactModels // unset non-touching neighbors // TODO even if shearupdate == false? if(scdata.contact_flags) *scdata.contact_flags &= ~CONTACT_TANGENTIAL_MODEL; + if(!scdata.contact_history) + return; //DO NOT access contact_history if not available double * const shear = &scdata.contact_history[history_offset]; shear[0] = 0.0; shear[1] = 0.0; diff --git a/src/tracking_mesh_I.h b/src/tracking_mesh_I.h index 710e80df2da2883aa7e61a19fe2e8277ce434f07..842e809718fb7ae8e7414d701bdc182119d95b9b 100644 --- a/src/tracking_mesh_I.h +++ b/src/tracking_mesh_I.h @@ -84,9 +84,8 @@ if(MultiNodeMeshParallel<NUM_NODES>::addElement(nodeToAdd)) { - // tracking mesh add memory - - customValues_.grow(this->sizeLocal()); + // tracking mesh add one element, grow memory if necessary + customValues_.addZeroElement(); // set ID for element // ID starts from 0 diff --git a/src/tri_mesh.h b/src/tri_mesh.h index 60f73dda151c300da0b5a6c84f35ed39cebe437b..d3f316c0cfcc195d6cacce27a1f5560dea643336 100644 --- a/src/tri_mesh.h +++ b/src/tri_mesh.h @@ -48,6 +48,7 @@ #include "atom.h" #include "math_extra_liggghts.h" #include "tri_line.h" +#include "region_neighbor_list.h" #include "superquadric_flag.h" #ifdef TRI_LINE_ACTIVE_FLAG @@ -73,9 +74,9 @@ namespace LAMMPS_NS TriMesh(LAMMPS *lmp); virtual ~TriMesh(); - double resolveTriSphereContact(int iPart, int nTri, double rSphere, double *cSphere, double *delta); + double resolveTriSphereContact(int iPart, int nTri, double rSphere, double *cSphere, double *delta,int &barysign); double resolveTriSphereContactBary(int iPart, int nTri, double rSphere, double *cSphere, - double *contactPoint,double *bary); + double *contactPoint,double *bary,int &barysign); #ifdef SUPERQUADRIC_ACTIVE_FLAG @@ -96,9 +97,9 @@ namespace LAMMPS_NS #ifdef TRI_LINE_ACTIVE_FLAG // Extra for Line Contact Calculation ******** double resolveTriSegmentContact (int iPart, int nTri, double *line, double *cLine, double length, double cylRadius, - double *delta, double &segmentParameter); + double *delta, double &segmentParameter,int &barysign); double resolveTriSegmentContactBary(int iPart, int nTri, double *line, double *cLine, double length, double cylRadius, - double *delta, double &segmentParameter, double *bary); + double *delta, double &segmentParameter, double *bary,int &barysign); bool resolveTriSegmentNeighbuild(int nTri, double *line, double *cLine, double length, double cylRadius, double treshold); // Extra for Line Contact Calculation ******** #endif diff --git a/src/tri_mesh_I.h b/src/tri_mesh_I.h index ba006342ff76da113eceeb3e75011a2d640fd51f..24dfa157bf58dc09a0e38132e6ec0897de509eff 100644 --- a/src/tri_mesh_I.h +++ b/src/tri_mesh_I.h @@ -51,19 +51,19 @@ /* ---------------------------------------------------------------------- */ - inline double TriMesh::resolveTriSphereContact(int iPart,int nTri, double rSphere, double *cSphere, double *delta) + inline double TriMesh::resolveTriSphereContact(int iPart,int nTri, double rSphere, double *cSphere, double *delta,int &barysign) { // this is the overlap algorithm, neighbor list build is // coded in resolveTriSphereNeighbuild double bary[3]; - return resolveTriSphereContactBary(iPart,nTri,rSphere,cSphere,delta,bary); + return resolveTriSphereContactBary(iPart,nTri,rSphere,cSphere,delta,bary,barysign); } /* ---------------------------------------------------------------------- */ inline double TriMesh::resolveTriSphereContactBary(int iPart, int nTri, double rSphere, - double *cSphere, double *delta, double *bary) + double *cSphere, double *delta, double *bary,int &barySign) { double **n = node_(nTri); int obtuseAngleIndex = SurfaceMeshBase::obtuseAngleIndex(nTri); @@ -77,7 +77,7 @@ MathExtraLiggghts::calcBaryTriCoords(node0ToSphereCenter,edgeVec(nTri),edgeLen(nTri),bary); double invlen = 1./(2.*rBound_(nTri)); - int barySign = (bary[0] > -precision_trimesh()*invlen) + 2*(bary[1] > -precision_trimesh()*invlen) + 4*(bary[2] > -precision_trimesh()*invlen); + barySign = (bary[0] > -precision_trimesh()*invlen) + 2*(bary[1] > -precision_trimesh()*invlen) + 4*(bary[2] > -precision_trimesh()*invlen); double d(0.); @@ -169,7 +169,8 @@ //double d(1.); double *n = node_(iTri)[iNode]; - if(obtuse){ + if(obtuse) + { double **edge = edgeVec(iTri); double nodeToP[3], closestPoint[3]; @@ -178,7 +179,7 @@ double distFromNode = vectorDot3D(nodeToP,edge[ipp]); if(distFromNode < SMALL_TRIMESH) - { + { if(distFromNode > -edgeLen(iTri)[ipp]){ if(!edgeActive(iTri)[ipp]) @@ -199,17 +200,17 @@ bary[ipp] = 1.; bary[iNode] = bary[ip] = 0.; return calcDist(p,node_(iTri)[ipp],delta); } - } + } distFromNode = vectorDot3D(nodeToP,edge[iNode]); if(distFromNode > -SMALL_TRIMESH) - { + { if(distFromNode < edgeLen(iTri)[iNode]){ if(!edgeActive(iTri)[iNode]) return LARGE_TRIMESH; - vectorAddMultiple3D(n,distFromNode,edge[ipp],closestPoint); + vectorAddMultiple3D(n,distFromNode,edge[iNode],closestPoint); bary[ipp] = 0.; bary[iNode] = 1. - distFromNode/edgeLen(iTri)[iNode]; @@ -223,9 +224,8 @@ bary[ip] = 1.; bary[iNode] = bary[ipp] = 0.; return calcDist(p,node_(iTri)[ip],delta); - } - } + } } if(!cornerActive(iTri)[iNode]) diff --git a/src/universe.cpp b/src/universe.cpp index da11ee5b5ac728f8884c98424d8c3a7a6a402c7e..9fb1ab3c5e3c1fd8217bac65428c75321034f997 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -72,7 +72,8 @@ Universe::Universe(LAMMPS *lmp, MPI_Comm communicator) : Pointers(lmp) { version = new char[strlen(LAMMPS_VERSION)+strlen(LIGGGHTS_VERSION)+100]; - sprintf(version,"Version %s based on LAMMPS %s",LIGGGHTS_VERSION,LAMMPS_VERSION); + //sprintf(version,"Version %s based on LAMMPS %s",LIGGGHTS_VERSION,LAMMPS_VERSION); + sprintf(version,"Version %s",LIGGGHTS_VERSION); uworld = uorig = communicator; MPI_Comm_rank(uworld,&me); diff --git a/src/update.cpp b/src/update.cpp index 390fb0375102c3d7a61a759142a7ec3b22be30b8..0806bb584e98611baf15936ff31fc016433946d7 100644 --- a/src/update.cpp +++ b/src/update.cpp @@ -102,6 +102,8 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp) str = (char *) "cg"; create_minimize(1,&str); + + force_dt_reset_ = false; } /* ---------------------------------------------------------------------- */ @@ -456,7 +458,7 @@ void Update::reset_timestep(bigint newstep) output->reset_timestep(ntimestep); for (int i = 0; i < modify->nfix; i++) { - if (modify->fix[i]->time_depend) + if (modify->fix[i]->time_depend && !force_dt_reset_) error->all(FLERR, "Cannot reset timestep with a time-dependent fix defined"); modify->fix[i]->reset_timestep(ntimestep,oldtimestep); diff --git a/src/update.h b/src/update.h index 6d9506e37472e1651b5cdfca7ea093c43b5972a3..73715ab887f5f58cb725ace25855cbaacc3dc68c 100644 --- a/src/update.h +++ b/src/update.h @@ -89,9 +89,13 @@ class Update : protected Pointers { void update_time(); bigint memory_usage(); + void set_force_dt_reset(bool value) + { force_dt_reset_ = value; } + private: void new_integrate(char *, int, char **, char *, int &); + bool force_dt_reset_; }; } diff --git a/src/utils.h b/src/utils.h index 8104c90d7a70e9cc6ab52cd0b3d0009bfaa42ce8..d7596ca486451c4365a3229d14fa5b58b70c7b51 100644 --- a/src/utils.h +++ b/src/utils.h @@ -53,6 +53,19 @@ namespace LIGGGHTS { using namespace LAMMPS_NS; namespace Utils { + + template <typename T> + inline T* ptr_reduce(T** &t) + { return &(t[0][0]); } + + template <typename T> + inline T* ptr_reduce(T* &t) + { return t; } + + template <typename T> + inline T* ptr_reduce(T &t) + { return &t; } + template<typename Interface> class AbstractFactory { typedef typename Interface::ParentType ParentType; diff --git a/src/variable.h b/src/variable.h index 399fa0e6a10e75e3b925cebe175110d66d7176ef..558faf47234dfda6ae48befa9aeb39a39724151a 100644 --- a/src/variable.h +++ b/src/variable.h @@ -52,6 +52,9 @@ namespace LAMMPS_NS { class Variable : protected Pointers { + + friend class Info; + public: Variable(class LAMMPS *); ~Variable(); diff --git a/src/vector_container.h b/src/vector_container.h index ee08217b48b388da13d179ba13a0407cb94bca41..cb1ed7bd9412ab362f34188208850e83d733ea04 100644 --- a/src/vector_container.h +++ b/src/vector_container.h @@ -130,8 +130,8 @@ namespace LAMMPS_NS { if(GeneralContainer<T,1,LEN_VEC>::numElem_ == GeneralContainer<T,1,LEN_VEC>::maxElem_) { - grow(GeneralContainer<T,1,LEN_VEC>::arr_,GeneralContainer<T,1,LEN_VEC>::maxElem_+GROW,1,LEN_VEC); - GeneralContainer<T,1,LEN_VEC>::maxElem_ += GROW; + grow(GeneralContainer<T,1,LEN_VEC>::arr_,GeneralContainer<T,1,LEN_VEC>::maxElem_+GROW_CONTAINER(),1,LEN_VEC); + GeneralContainer<T,1,LEN_VEC>::maxElem_ += GROW_CONTAINER(); } for(int i=0;i<LEN_VEC;i++) GeneralContainer<T,1,LEN_VEC>::arr_[GeneralContainer<T,1,LEN_VEC>::numElem_][0][i] = elem[i]; diff --git a/src/vector_liggghts.h b/src/vector_liggghts.h index 9dd3cbe82e12b6f3e8f8e854c45f88f523812ed4..79025384d5c623c737377a774b58a80fe622c597 100644 --- a/src/vector_liggghts.h +++ b/src/vector_liggghts.h @@ -238,7 +238,7 @@ inline int vectorMax3D(int *v) return v[2]; } -inline int vectorMaxN(int *v, int n) +inline int vectorMaxN(const int *v, const int n) { int max = v[0]; for (int i=1;i<n;i++) @@ -246,7 +246,15 @@ inline int vectorMaxN(int *v, int n) return max; } -inline int vectorMinN(int *v, int n) +inline double vectorMaxN(const double *v, const int n) +{ + double max = v[0]; + for (int i=1;i<n;i++) + max = max > v[i] ? max : v[i]; + return max; +} + +inline int vectorMinN(const int *v, const int n) { int min = v[0]; for (int i=1;i<n;i++) @@ -254,6 +262,14 @@ inline int vectorMinN(int *v, int n) return min; } +inline double vectorMinN(const double *v, const int n) +{ + double min = v[0]; + for (int i=1;i<n;i++) + min = min < v[i] ? min : v[i]; + return min; +} + inline void vectorComponentAbs3D(double *v) { if(v[0] < 0.) @@ -458,6 +474,25 @@ inline void vectorSubtract2D(const double *v1,const double *v2, double *result) result[1]=v1[1]-v2[1]; } +inline void vectorMultiN(const double *v1, const double *v2, double *result, const int n) +{ + for(int i = 0; i < n; i++) + result[i] = v1[i] * v2[i]; +} + +inline void vectorMultiN(const int *v1, const int *v2, int *result, const int n) +{ + for(int i = 0; i < n; i++) + result[i] = v1[i] * v2[i]; +} + +template<typename T> +inline void vectorComponentDivN(const T *v1, const T *v2, T *result, const int n) +{ + for(int i = 0; i < n; i++) + result[i] = v1[i] / v2[i]; +} + inline void vectorCross3D(const double *v1,const double *v2, double *result) { result[0]=v1[1]*v2[2]-v1[2]*v2[1]; @@ -639,7 +674,7 @@ inline void printVec4D(FILE *out, const char *name, double *vec) inline void printVecN(FILE *out, const char *name, double *vec, int n) { - fprintf(out," vector %s:",name); + if(name) fprintf(out," vector %s:",name); for(int i = 0; i < n; i++) fprintf(out,"%f ",vec[i]); fprintf(out,"\n"); @@ -647,7 +682,7 @@ inline void printVecN(FILE *out, const char *name, double *vec, int n) inline void printVecN(FILE *out, const char *name, int *vec, int n) { - fprintf(out," vector %s:",name); + if(name) fprintf(out," vector %s:",name); for(int i = 0; i < n; i++) fprintf(out,"%d ",vec[i]); fprintf(out,"\n"); diff --git a/src/velocity.cpp b/src/velocity.cpp index a7e032d96965f8cad5b868cea233256d72d0894d..39962ed4ebe238bb8d98d619a41a1726b60d0664 100644 --- a/src/velocity.cpp +++ b/src/velocity.cpp @@ -257,6 +257,10 @@ void Velocity::setAngular(int narg, char **arg) error->all(FLERR,"Cannot set variable z velocity for 2d simulation"); } + // other error checks + if (!atom->angmom_flag) + error->all(FLERR,"setAngular requires the atom property 'angmom' as defined by atom_style ellipsoid."); + // allocate vfield array if necessary double **vfield = NULL; @@ -266,7 +270,7 @@ void Velocity::setAngular(int narg, char **arg) double **angmom = atom->angmom; int *mask = atom->mask; - int nlocal = atom->nlocal; + int nlocal = atom->nlocal; if (varflag == CONSTANT) { for (int i = 0; i < nlocal; i++) { diff --git a/src/version_liggghts.h b/src/version_liggghts.h index d19b542a3355aefe9becca757c1d02f9980802e6..c8988f51ce905043c2ae59a3f62bd1ae0de8453f 100644 --- a/src/version_liggghts.h +++ b/src/version_liggghts.h @@ -1 +1 @@ -#define LIGGGHTS_VERSION "LIGGGHTS-PUBLIC 3.3.1, compiled 2016-01-14-14:02:34 by kloss, git commit 9b1fc57b77c483deaf2c0a6c69241c5d4f91e3c2" +#define LIGGGHTS_VERSION "LIGGGHTS-PUBLIC 3.4.0, compiled 2016-05-17-21:57:06 by kloss, git commit 99507f5217ad4fd4be5107d6262bd7274c9a5c03" diff --git a/src/version_liggghts.txt b/src/version_liggghts.txt index bea438e9ade7708f8a0fc26bdacda06231f4a434..18091983f59ddde8105e566545a0d9e4a12a4f1c 100644 --- a/src/version_liggghts.txt +++ b/src/version_liggghts.txt @@ -1 +1 @@ -3.3.1 +3.4.0