Author: eudoxos
Date: 2009-06-30 22:10:30 +0200 (Tue, 30 Jun 2009)
New Revision: 1826

Modified:
   trunk/SConstruct
   trunk/gui/SConscript
   trunk/gui/py/_packPredicates.cpp
   trunk/gui/py/pack.py
   trunk/lib/SConscript
   
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingBox4InteractionOfMyTetrahedron.cpp
   
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingMyTetrahedron4InteractionOfMyTetrahedron.cpp
   trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp
   trunk/scripts/test/gts-operators.py
Log:
1. Fix crashers in InteractingMyTetrahedron* classes (introduced by me when 
updating interaction logic)
2. Reimplement inGtsSurface in c/c++ which makes it faster due to pygts 
interface limitations (addressed on pygts mailing list meanwhile), but is dirty 
programming.
3. Set CCOMSTR to correspond to CXXCOMSTR in SConstruct (to show nice line when 
compiling c source file, for pygts)
4. Set good-looking timestep in the TetrahedronsTest generator



Modified: trunk/SConstruct
===================================================================
--- trunk/SConstruct    2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/SConstruct    2009-06-30 20:10:30 UTC (rev 1826)
@@ -368,9 +368,10 @@
 if env['pretty']:
        ## http://www.scons.org/wiki/HidingCommandLinesInOutput
        env.Replace(CXXCOMSTR='C ${SOURCES}', # → ${TARGET.file}')
-               SHCXXCOMSTR='C ${SOURCES}',  #→ ${TARGET.file}')
-               SHLINKCOMSTR='L ${TARGET.file}', # → ${TARGET.file}')
-               LINKCOMSTR='L ${TARGET.file}', # → ${TARGET.file}')
+               CCOMSTR='C ${SOURCES}',
+               SHCXXCOMSTR='C ${SOURCES}', 
+               SHLINKCOMSTR='L ${TARGET.file}',
+               LINKCOMSTR='L ${TARGET.file}',
                INSTALLSTR='⇒ $TARGET',
                QT_UICCOMSTR='U ${SOURCES}',
                QT_MOCCOMSTR='M ${SOURCES}')

Modified: trunk/gui/SConscript
===================================================================
--- trunk/gui/SConscript        2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/gui/SConscript        2009-06-30 20:10:30 UTC (rev 1826)
@@ -73,9 +73,12 @@
                                'Clump'
                        ],
                        ),
-               env.SharedLibrary('_utils',['py/_utils.cpp'],SHLIBPREFIX='',
-                       LIBS=env['LIBS']+['Shop','ConcretePM']),
-               
env.SharedLibrary('_packPredicates',['py/_packPredicates.cpp'],SHLIBPREFIX=''),
+               
env.SharedLibrary('_utils',['py/_utils.cpp'],SHLIBPREFIX='',LIBS=env['LIBS']+['Shop','ConcretePM']),
+               
env.SharedLibrary('_packPredicates',['py/_packPredicates.cpp'],SHLIBPREFIX='',
+                       # if we compile with GTS, link to the python module, as 
inGtsSurface uses some of its symbols.
+                       # because the module doesn't have the lib- suffix, we 
put it directly to SHLINKFLAGS
+                       # using the -l: syntax (see man ld) and declare the 
dependency below
+                       
SHLINKFLAGS=env['SHLINKFLAGS']+(['-l:$PREFIX/lib/yade$SUFFIX/py/gts/_gts.so'] 
if 'GTS' in env['features'] else [])),
                
env.SharedLibrary('_eudoxos',['py/_eudoxos.cpp'],SHLIBPREFIX='',CXXFLAGS=env['CXXFLAGS']+([]
 if not os.path.exists('../../brefcom-mm.hh') else 
['-include','../brefcom-mm.hh']),LIBS=env['LIBS']+['Shop','ConcretePM']),
                env.SharedLibrary('log',['py/log.cpp'],SHLIBPREFIX=''),
                env.File('__init__.py','py'),
@@ -90,5 +93,7 @@
                env.File('pack.py','py'),
        ])
        if os.path.exists('../../brefcom-mm.hh'): 
Depends('py/_eudoxos.cpp','../../brefcom-mm.hh')
+       # see comments for _packPredicates above
+       if 'GTS' in env['features']: 
env.Depends('_packPredicates.so','$PREFIX/lib/yade$SUFFIX/py/gts/_gts.so')
 
 

Modified: trunk/gui/py/_packPredicates.cpp
===================================================================
--- trunk/gui/py/_packPredicates.cpp    2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/gui/py/_packPredicates.cpp    2009-06-30 20:10:30 UTC (rev 1826)
@@ -269,7 +269,61 @@
                return 
vvec2ttuple(Vector3r(-inf,-inf,-inf),Vector3r(inf,inf,inf)); }
 };
 
+#ifdef YADE_GTS
+extern "C" {
+#include<yade/lib-py/pygts.h>
+}
+/* Helper function for inGtsSurface::aabb() */
+static void vertex_aabb(GtsVertex *vertex, pair<Vector3r,Vector3r> *bb)
+{
+       GtsPoint *_p=GTS_POINT(vertex);
+       Vector3r p(_p->x,_p->y,_p->z);
+       bb->first=componentMinVector(bb->first,p);
+       bb->second=componentMaxVector(bb->second,p);
+}
 
+/*
+This class plays tricks getting aroung pyGTS to get GTS objects and cache bb 
tree to speed
+up point inclusion tests. For this reason, we have to link with _gts.so (see 
corresponding
+SConscript file), which is at the same time the python module.
+*/
+class inGtsSurface: public Predicate{
+       python::object pySurf; // to hold the reference so that surf is valid
+       GtsSurface *surf;
+       bool is_open, noPad, noPadWarned;
+       GNode* tree;
+public:
+       inGtsSurface(python::object _surf, bool _noPad=false): pySurf(_surf), 
noPad(_noPad), noPadWarned(false) {
+               if(!pygts_surface_check(_surf.ptr())) throw 
invalid_argument("Ctor must receive a gts.Surface() instance."); 
+               surf=PYGTS_SURFACE_AS_GTS_SURFACE(PYGTS_SURFACE(_surf.ptr()));
+               if(!gts_surface_is_closed(surf)) throw 
invalid_argument("Surface is not closed.");
+               is_open=gts_surface_volume(surf)<0.;
+               if((tree=gts_bb_tree_surface(surf))==NULL) throw 
runtime_error("Could not create GTree.");
+       }
+       ~inGtsSurface(){g_node_destroy(tree);}
+       python::tuple aabb() const {
+               Real inf=std::numeric_limits<Real>::infinity();
+               pair<Vector3r,Vector3r> bb; bb.first=Vector3r(inf,inf,inf); 
bb.second=Vector3r(-inf,-inf,-inf);
+               gts_surface_foreach_vertex(surf,(GtsFunc)vertex_aabb,&bb);
+               return vvec2ttuple(bb.first,bb.second);
+       }
+       bool ptCheck(Vector3r pt) const{
+               GtsPoint gp; gp.x=pt[0]; gp.y=pt[1]; gp.z=pt[2];
+               return (bool)gts_point_is_inside_surface(&gp,tree,is_open);
+       }
+       bool operator()(python::tuple _pt, Real pad=0.) const {
+               Vector3r pt=tuple2vec(_pt);
+               if(noPad){
+                       if(pad!=0. && noPadWarned) LOG_WARN("inGtsSurface 
constructed with noPad; requested non-zero pad set to zero.");
+                       return ptCheck(pt);
+               }
+               return ptCheck(pt) && ptCheck(pt-Vector3r(pad,0,0)) && 
ptCheck(pt+Vector3r(pad,0,0)) && ptCheck(pt-Vector3r(0,pad,0))&& 
ptCheck(pt+Vector3r(0,pad,0)) && ptCheck(pt-Vector3r(0,0,pad))&& 
ptCheck(pt+Vector3r(0,0,pad));
+       }
+};
+
+#endif
+
+
 BOOST_PYTHON_MODULE(_packPredicates){
        // base predicate class
        python::class_<PredicateWrap,/* necessary, as methods are pure 
virtual*/ boost::noncopyable>("Predicate")
@@ -290,5 +344,8 @@
        python::class_<inHyperboloid,python::bases<Predicate> 
>("inHyperboloid","Hyperboloid 
predicate",python::init<python::tuple,python::tuple,Real,Real>(python::args("centerBottom","centerTop","radius","skirt"),"Ctor
 taking centers of the lateral walls (as 3-tuples), radius at bases and skirt 
(middle radius)."));
        python::class_<inEllipsoid,python::bases<Predicate> 
>("inEllipsoid","Ellipsoid 
predicate",python::init<python::tuple,python::tuple>(python::args("centerPoint","abc"),"Ctor
 taking center of the ellipsoid (3-tuple) and its 3 radii (3-tuple)."));
        python::class_<notInNotch,python::bases<Predicate> 
>("notInNotch","Outside of infinite, rectangle-shaped notch 
predicate",python::init<python::tuple,python::tuple,python::tuple,Real>(python::args("centerPoint","edge","normal","aperture"),"Ctor
 taking point in the symmetry plane, vector pointing along the edge, plane 
normal and aperture size.\nThe side inside the notch is edge×normal.\nNormal is 
made perpendicular to the edge.\nAll vectors are normalized at construction 
time.")); 
+       #ifdef YADE_GTS
+               python::class_<inGtsSurface,python::bases<Predicate> 
>("inGtsSurface","GTS surface 
predicate",python::init<python::object,python::optional<bool> 
>(python::args("surface","noPad"),"Ctor taking a gts.Surface() instance, which 
must not be modified during instance lifetime.\nThe optional noPad can disable 
padding (if set to True), which speeds up calls several times.\nNote: padding 
checks inclusion of 6 points along +- cardinal directions in the pad distance 
from given point, which is not exact."));
+       #endif
 }
 

Modified: trunk/gui/py/pack.py
===================================================================
--- trunk/gui/py/pack.py        2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/gui/py/pack.py        2009-06-30 20:10:30 UTC (rev 1826)
@@ -13,9 +13,16 @@
 # make c++ predicates available in this module
 from _packPredicates import *
 
+class inGtsSurface_py(Predicate):
+       """This class was re-implemented in c++, but should stay here to serve 
as reference for implementing
+       Predicates in pure python code. C++ allows us to play dirty tricks in 
GTS which are not accessible
+       through pygts itself; the performance penalty of pygts comes from fact 
that if constructs and destructs
+       bb tree for the surface at every invocation of gts.Point().is_inside(). 
That is cached in the c++ code,
+       provided that the surface is not manipulated with during lifetime of 
the object (user's responsibility).
 
-class inGtsSurface(Predicate):
-       """Predicate for GTS surfaces. Constructed using an already existing 
surfaces, which must be closed.
+       ---
+       
+       Predicate for GTS surfaces. Constructed using an already existing 
surfaces, which must be closed.
 
                import gts
                surf=gts.read(open('horse.gts'))
@@ -25,13 +32,13 @@
        must be enabled in the ctor by saying doSlowPad=True. If it is not 
enabled and pad is not zero,
        warning is issued.
        """
-       def __init__(self,surf,doSlowPad=False):
+       def __init__(self,surf,noPad=False):
                # call base class ctor; necessary for virtual methods to work 
as expected.
                # see comments in _packPredicates.cpp for struct PredicateWrap.
                super(inGtsSurface,self).__init__()
                if not surf.is_closed(): raise RuntimeError("Surface for 
inGtsSurface predicate must be closed.")
                self.surf=surf
-               self.doSlowPad=doSlowPad
+               self.noPad=noPad
                inf=float('inf')
                mn,mx=[inf,inf,inf],[-inf,-inf,-inf]
                for v in surf.vertices():
@@ -42,8 +49,8 @@
        def aabb(self): return self.mn,self.mx
        def __call__(self,_pt,pad=0.):
                p=gts.Point(*_pt)
-               if not self.doSlowPad:
-                       if pad!=0: warnings.warn("Pad distance not supported 
for GTS surfaces, using 0 instead.")
+               if self.noPad:
+                       if pad!=0: warnings.warn("Padding disabled in ctor, 
using 0 instead.")
                        return p.is_inside(self.surf)
                
pp=[gts.Point(_pt[0]-pad,_pt[1],_pt[2]),gts.Point(_pt[0]+pad,_pt[1],_pt[2]),gts.Point(_pt[0],_pt[1]-pad,_pt[2]),gts.Point(_pt[0],_pt[1]+pad,_pt[2]),gts.Point(_pt[0],_pt[1],_pt[2]-pad),gts.Point(_pt[0],_pt[1],_pt[2]+pad)]
                return p.is_inside(self.surf) and pp[0].is_inside(self.surf) 
and pp[1].is_inside(self.surf) and pp[2].is_inside(self.surf) and 
pp[3].is_inside(self.surf) and pp[4].is_inside(self.surf) and 
pp[5].is_inside(self.surf)

Modified: trunk/lib/SConscript
===================================================================
--- trunk/lib/SConscript        2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/lib/SConscript        2009-06-30 20:10:30 UTC (rev 1826)
@@ -79,7 +79,12 @@
                env.File('py/pygts-0.3.1/__init__.py'),
                env.File('py/pygts-0.3.1/pygts.py')
        ])
+       #env.Install('$PREFIX/lib/yade$SUFFIX/lib',[
+       #       # the same, but to link the pack module with
+       #       
env.SharedLibrary('_gts',['py/pygts-0.3.1/cleanup.c','py/pygts-0.3.1/edge.c','py/pygts-0.3.1/face.c','py/pygts-0.3.1/object.c','py/pygts-0.3.1/point.c','py/pygts-0.3.1/pygts.c','py/pygts-0.3.1/segment.c','py/pygts-0.3.1/surface.c','py/pygts-0.3.1/triangle.c','py/pygts-0.3.1/vertex.c'],CPPDEFINES=env['CPPDEFINES']+['PYGTS_HAS_NUMPY']),
+       #])
 
+
 env.Install('$PREFIX/lib/yade$SUFFIX/lib',[
 
        env.SharedLibrary('yade-base',

Modified: 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingBox4InteractionOfMyTetrahedron.cpp
===================================================================
--- 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingBox4InteractionOfMyTetrahedron.cpp
      2009-06-29 22:09:04 UTC (rev 1825)
+++ 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingBox4InteractionOfMyTetrahedron.cpp
      2009-06-30 20:10:30 UTC (rev 1826)
@@ -74,7 +74,7 @@
 
        shared_ptr<InteractionOfMyTetrahedron> imt;
        // depending whether it's a new interaction: create new one, or use the 
existing one.
-       if (c->interactionGeometry)
+       if (!c->interactionGeometry)
                imt = shared_ptr<InteractionOfMyTetrahedron>(new 
InteractionOfMyTetrahedron());
        else
                imt = 
YADE_PTR_CAST<InteractionOfMyTetrahedron>(c->interactionGeometry);        

Modified: 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingMyTetrahedron4InteractionOfMyTetrahedron.cpp
===================================================================
--- 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingMyTetrahedron4InteractionOfMyTetrahedron.cpp
    2009-06-29 22:09:04 UTC (rev 1825)
+++ 
trunk/pkg/dem/Engine/EngineUnit/InteractingMyTetrahedron2InteractingMyTetrahedron4InteractionOfMyTetrahedron.cpp
    2009-06-30 20:10:30 UTC (rev 1826)
@@ -36,10 +36,10 @@
        
        shared_ptr<InteractionOfMyTetrahedron> imt;
        // depending whether it's a new interaction: create new one, or use the 
existing one.
-       if (c->interactionGeometry)
+       if (!c->interactionGeometry)
                imt = shared_ptr<InteractionOfMyTetrahedron>(new 
InteractionOfMyTetrahedron());
        else
-               imt = 
YADE_PTR_CAST<InteractionOfMyTetrahedron>(c->interactionGeometry);        
+               imt = 
YADE_PTR_CAST<InteractionOfMyTetrahedron>(c->interactionGeometry);
 
        bool isInteracting = false;
        for(int i=0 ; i<4 ; ++i )
@@ -66,7 +66,6 @@
                                isInteracting = true;
                }
 
-
        c->interactionGeometry = imt;
        return isInteracting;
 }

Modified: trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp     2009-06-29 22:09:04 UTC 
(rev 1825)
+++ trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp     2009-06-30 20:10:30 UTC 
(rev 1826)
@@ -153,8 +153,10 @@
                                setProgress(current++/all);
                        }
        }
+
+       rootBody->dt=1e-2;
        
-       message="foo bar "+boost::lexical_cast<std::string>(42);
+       message="";
        return true;
 }
 

Modified: trunk/scripts/test/gts-operators.py
===================================================================
--- trunk/scripts/test/gts-operators.py 2009-06-29 22:09:04 UTC (rev 1825)
+++ trunk/scripts/test/gts-operators.py 2009-06-30 20:10:30 UTC (rev 1826)
@@ -3,7 +3,9 @@
 create union of surfaces using GTS calls first and use a single
 isGtsSurface as predicate with the united surface.
 
-Surprisingly, the first variant seems faster.
+The disadvantage of the predicate union | is that each sphere must fit whole 
in one
+surface or another: with padding, several points on the sphere are tested. 
Therefore,
+areas near both surfaces' boundary will not be filled at all.
 
 Note that GTS only moves references to surfaces around, therefore e.g. 
translating
 surface that is part of the union will move also the part of the united 
surface.
@@ -17,7 +19,7 @@
 
O.bodies.append(pack.gtsSurface2Facets(s1,color=(0,1,0))+pack.gtsSurface2Facets(s2,color=(1,0,0)))
 
 s12=gts.Surface(); s12.copy(s1.union(s2)); s12.translate(0,0,.1)
-radius=0.005
+radius=0.002
 O.bodies.append(pack.gtsSurface2Facets(s12,color=(0,0,1)))
 
 qt.View()
@@ -29,4 +31,3 @@
 
O.bodies.append(pack.regularHexa(pack.inGtsSurface(s12),radius,gap=0.,color=(1,0,0)))
 t2=time()
 print 'Using surface union: %gs'%(t2-t1)
-


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to