yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #05065
[Branch ~yade-dev/yade/trunk] Rev 2320: 1. Add show Paraview documentation to the postprocessing section
------------------------------------------------------------
revno: 2320
fixes bug(s): https://launchpad.net/bugs/601866
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Mon 2010-07-05 15:41:14 +0200
message:
1. Add show Paraview documentation to the postprocessing section
2. Fix at least partially the rotated cell bug in shift2 (https://bugs.launchpad.net/yade/+bug/601866), still some issues elsewhere, though.
added:
doc/sphinx/fig/paraview-glyph-icon.png
doc/sphinx/fig/paraview-open-files.png
doc/sphinx/fig/paraview-rendering-apply.png
modified:
doc/sphinx/user.rst
examples/funnel.py
pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp
pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp
pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp
scripts/test/periodic-grow.py
--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== added file 'doc/sphinx/fig/paraview-glyph-icon.png'
Binary files doc/sphinx/fig/paraview-glyph-icon.png 1970-01-01 00:00:00 +0000 and doc/sphinx/fig/paraview-glyph-icon.png 2010-07-05 13:41:14 +0000 differ
=== added file 'doc/sphinx/fig/paraview-open-files.png'
Binary files doc/sphinx/fig/paraview-open-files.png 1970-01-01 00:00:00 +0000 and doc/sphinx/fig/paraview-open-files.png 2010-07-05 13:41:14 +0000 differ
=== added file 'doc/sphinx/fig/paraview-rendering-apply.png'
Binary files doc/sphinx/fig/paraview-rendering-apply.png 1970-01-01 00:00:00 +0000 and doc/sphinx/fig/paraview-rendering-apply.png 2010-07-05 13:41:14 +0000 differ
=== modified file 'doc/sphinx/user.rst'
--- doc/sphinx/user.rst 2010-05-17 08:51:45 +0000
+++ doc/sphinx/user.rst 2010-07-05 13:41:14 +0000
@@ -1250,6 +1250,81 @@
Postprocessing
***************
+3d rendering & videos
+======================
+
+There are multiple ways to produce a video of simulation:
+
+#. Capture screen output (the 3d rendering window) during the simulation â there are tools available for that (such as `Istanbul <http://live.gnome.org/Istanbul>`_ or `RecordMyDesktop <http://recordmydesktop.sourceforge.net/about.php>`_, which are also packaged for most Linux distributions). The output is "what you see is what you get", with all the advantages and disadvantages.
+
+#. Periodic frame snapshot using :yref:`SnapshotEngine` (see :ysrc:`examples/bulldozer.py` for a full example)::
+
+ O.engines=[
+ #...
+ SnapshotEngine(iterPeriod=100,fileBase='/tmp/bulldozer-',viewNo=0,label='snapshooter')
+ ]
+
+ which will save numbered files like ``/tmp/bulldozer-0000.png``. These files can be processed externally (with `mencoder <http://www.mplayerhq.hu>`_ and similar tools) or directly with the :yref:`yade.utils.encodeVideoFromFrames`::
+
+ utils.encodeVideoFromFrames(snapshooter.savedSnapshots,out='/tmp/bulldozer.ogg',fps=2)
+
+ The video is encoded in the `Theora <http://www.theora.org>`_ format stored in an ogg container.
+
+#. Specialized post-processing tools, notably `Paraview <http://www.paraview.org>`_. This is described in more detail in the following section.
+
+Paraview
+---------
+
+Saving data during the simulation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Paraview is based on the `Visualization Toolkit <http://www.vtk.org>`_, which defines formats for saving various types of data. One of them (with the ``.vtu`` extension) can be written by a special engine :yref:`VTKRecorder`. It is added to the simulation loop::
+
+ O.engines=[
+ # ...
+ VTKRecorder(iterPeriod=100,recorders=['spheres','facets','colors'],fileName='/tmp/p1-')
+ ]
+
+* :yref:`iterPeriod<PeriodicEngine.iterPeriod>` determines how often to save simulation data (besides :yref:`iterPeriod<PeriodicEngine.iterPeriod>`, you can also use :yref:`virtPeriod<PeriodicEngine.virtPeriod>` or :yref:`realPeriod<PeriodicEngine.realPeriod>`). It the period is too high (and data are saved only few times), the video will have few frames.
+* :yref:`fileName<VTKRecorder.fileName>` is the prefix for files being saved. In this case, output files will be named ``/tmp/p1-spheres.0.vtu`` and ``/tmp/p1-facets.0.vtu``, where the number is the number of iteration; many files are created, putting them in a separate directory is advisable.
+* :yref:`recorders<VTKRecorder.recorders>` determines what data to save (see the :yref:`documentation<VTKRecorder.recorders>`)
+
+Loading data into Paraview
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All sets of files (``spheres``, ``facets``, â¦) must be opened one-by-one in Paraview. The open dialogue automatically collapses numbered files in one, making it easy to select all of them:
+
+.. _img-paraview-open-files:
+.. figure:: fig/paraview-open-files.png
+
+Click on the "Apply" button in the "Object inspector" sub-window to make loaded objects visible. You can see tree of displayed objects in the "Pipeline browser":
+
+.. _img-paraview-rendering-apply:
+.. figure:: fig/paraview-rendering-apply.png
+
+Rendering spherical particles
+"""""""""""""""""""""""""""""
+
+.. |paraview-glyph-icon| image:: fig/paraview-glyph-icon.png
+
+Spheres will only appear as points. To make them look as spheres, you have to add "glyph" to the ``p1-spheres.*`` item in the pipeline using the |paraview-glyph-icon| icon. Then set (in the Object insepector)
+
+* "Glyph type" to *Sphere*
+* "Radius" to *1*
+* "Scale mode" to *Scalar* (*Scalar* is set above to be the *radii* value saved in the file, therefore spheres with radius *1* will be scaled by their true radius)
+* "Set scale factor" to *1*
+* optionally uncheck "Mask points" and "Random mode" (they make some particles not to be rendered for performance reasons, controlled by the "Maximum Number of Points")
+
+After clicking "Apply", spheres will appear. They will be rendered over the original white points, which you can disable by clicking on the eye icon next to ``p1-spheres.*`` in the Pipeline browser.
+
+Facet transparency
+"""""""""""""""""""
+If you want to make facet objects transparent, select ``p1-facets.*`` in the Pipline browser, then go to the Object inspector on the Display tab. Under "Style", you can set the "Opacity" value to something smaller than 1.
+
+Animation
+""""""""""
+You can move between frames (snapshots that were saved) via the "Animation" menu. After setting the view angle, zoom etc to your satisfaction, the animation can be saved with *File/Save animation*.
+
**************
Extending Yade
=== modified file 'examples/funnel.py'
--- examples/funnel.py 2010-05-29 20:52:10 +0000
+++ examples/funnel.py 2010-07-05 13:41:14 +0000
@@ -27,7 +27,7 @@
),
GravityEngine(gravity=(0,0,-9.81)),
NewtonIntegrator(),
- VTKRecorder(iterPeriod=100,recorders=['spheres','facets','colors'],fileName='/tmp/p1')
+ VTKRecorder(iterPeriod=100,recorders=['spheres','facets','colors'],fileName='/tmp/p1-')
]
O.dt=utils.PWaveTimeStep()
=== modified file 'pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp'
--- pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2010-06-29 14:32:03 +0000
+++ pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2010-07-05 13:41:14 +0000
@@ -47,8 +47,8 @@
assert(callbackPtrs.size()==callbacks.size());
size_t callbacksSize=callbacks.size();
- // precompute transformed cell size
- Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cell->trsf*scene->cell->refSize;
+ // cache transformed cell size
+ Matrix3r cellHsize; if(scene->isPeriodic) cellHsize=scene->cell->Hsize;
// force removal of interactions that were not encountered by the collider
// (only for some kinds of colliders; see comment for InteractionContainer::iterColliderLastRun)
@@ -107,9 +107,9 @@
geomCreated=I->functorCache.geom->go(b1->shape,b2->shape, *b1->state, *b2->state, Vector3r::Zero(), /*force*/false, I);
#endif
} else { // handle periodicity
- Vector3r shift2(I->cellDist[0]*cellSize[0],I->cellDist[1]*cellSize[1],I->cellDist[2]*cellSize[2]);
+ Vector3r shift2=cellHsize*Vector3r(I->cellDist[0],I->cellDist[1],I->cellDist[2]);
// in sheared cell, apply shear on the mutual position as well
- shift2=scene->cell->shearPt(shift2);
+ //shift2=scene->cell->shearPt(shift2);
#ifdef YADE_DEVIRT_FUNCTORS
// cast back from void* first
geomCreated=(*((InteractionGeometryFunctor::StaticFuncPtr)I->functorCache.geomPtr))(I->functorCache.geom.get(),b1->shape,b2->shape,*b1->state,*b2->state,shift2,/*force*/false,I);
=== modified file 'pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp'
--- pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp 2010-05-04 13:56:05 +0000
+++ pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp 2010-07-05 13:41:14 +0000
@@ -455,3 +455,21 @@
return id1==3 || id2==3; //true; //id1==1 || id2==1;
}
#endif
+
+python::tuple InsertionSortCollider::dumpBounds(){
+ python::list bl[3]; // 3 bound lists, inserted into the tuple at the end
+ for(int axis=0; axis<3; axis++){
+ VecBounds& V=BB[axis];
+ if(periodic){
+ for(long i=0; i<V.size; i++){
+ long ii=V.norm(i); // start from the period boundary
+ bl[i].append(python::make_tuple(V[ii].coord,(V[ii].flags.isMin?-1:1)*V[ii].id,V[ii].period));
+ }
+ } else {
+ for(long i=0; i<V.size; i++){
+ bl[i].append(python::make_tuple(V[i].coord,(V[i].flags.isMin?-1:1)*V[i].id));
+ }
+ }
+ }
+ return python::make_tuple(bl[0],bl[1],bl[2]);
+}
=== modified file 'pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp'
--- pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp 2010-05-04 13:56:05 +0000
+++ pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp 2010-07-05 13:41:14 +0000
@@ -146,7 +146,8 @@
//! Whether the Scene was periodic (to detect the change, which shouldn't happen, but shouldn't crash us either)
bool periodic;
-
+ // return python representation of the BB struct, as ([...],[...],[...]).
+ python::tuple dumpBounds();
/*! sorting routine; insertion sort is very fast for strongly pre-sorted lists, which is our case
http://en.wikipedia.org/wiki/Insertion_sort has the algorithm and other details
@@ -219,6 +220,7 @@
/* py */
.def_readonly("strideActive",&InsertionSortCollider::strideActive,"Whether striding is active (read-only; for debugging). |yupdate|")
.def_readonly("periodic",&InsertionSortCollider::periodic,"Whether the collider is in periodic mode (read-only; for debugging) |yupdate|")
+ .def("dumpBounds",&InsertionSortCollider::dumpBounds,"Return representation of the internal sort data. The format is ``([...],[...],[...])`` for 3 axes, where each ``...`` is a list of entries (bounds). The entry is a tuple with the fllowing items:\n\n* coordinate (float)\n* body id (int), but negated for negative bounds\n* period numer (int), if the collider is in the periodic regime.");
);
DECLARE_LOGGER;
};
=== modified file 'scripts/test/periodic-grow.py'
--- scripts/test/periodic-grow.py 2010-03-22 17:39:33 +0000
+++ scripts/test/periodic-grow.py 2010-07-05 13:41:14 +0000
@@ -26,8 +26,8 @@
from yade import qt
qt.Controller(); qt.View()
O.run(200,True)
-rate=-1e-4*cubeSize/(O.dt*200)*Matrix3().IDENTITY
-O.cell['velGrad']=rate
+rate=-1e-3*cubeSize/(O.dt*200)*Matrix3.Identity
+O.cell.velGrad=rate
for i in range(0,25):
O.run(2000,True)
F,stiff=utils.totalForceInVolume()