Author: eudoxos
Date: 2009-06-03 00:02:25 +0200 (Wed, 03 Jun 2009)
New Revision: 1788

Modified:
   trunk/core/InteractionContainer.cpp
   trunk/core/InteractionContainer.hpp
   trunk/gui/py/_utils.cpp
   trunk/gui/py/utils.py
   trunk/lib/serialization/Archive.tpp
   trunk/pkg/dem/ConcretePM.cpp
   trunk/pkg/dem/ConcretePM.hpp
   trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp
Log:
1. Add epsNPl to Cpm
2. Replace vector<body_id_t> by Vector2<body_id_t> and make it properly 
serializable (should be faster)
3. Add function to compute forces on interactions crossing plane.
4. Replace custom xcombine function by itertools.product in grid sphere packing


Modified: trunk/core/InteractionContainer.cpp
===================================================================
--- trunk/core/InteractionContainer.cpp 2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/core/InteractionContainer.cpp 2009-06-02 22:02:25 UTC (rev 1788)
@@ -11,7 +11,7 @@
 #include "InteractionContainer.hpp"
 
 void InteractionContainer::requestErase(body_id_t id1, body_id_t id2){
-       find(id1,id2)->reset(); bodyIdPair v(0,2); v.push_back(id1); 
v.push_back(id2); 
+       find(id1,id2)->reset(); bodyIdPair v(id1,id2); //v.push_back(id1); 
v.push_back(id2); 
        #ifdef YADE_OPENMP
                boost::mutex::scoped_lock lock(pendingEraseMutex);
        #endif

Modified: trunk/core/InteractionContainer.hpp
===================================================================
--- trunk/core/InteractionContainer.hpp 2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/core/InteractionContainer.hpp 2009-06-02 22:02:25 UTC (rev 1788)
@@ -104,8 +104,8 @@
                virtual shared_ptr<Interaction>& operator[] (unsigned int) 
{throw;};
                virtual const shared_ptr<Interaction>& operator[] (unsigned 
int) const {throw;};
 
-               // std::pair is not handle by yade::serialization, use 
vector<body_id_t> instead
-               typedef vector<body_id_t> bodyIdPair;
+               // std::pair is not handled by yade::serialization, use 
vector<body_id_t> instead
+               typedef Vector2<body_id_t> bodyIdPair;
                //! Ask for erasing the interaction given (from the 
constitutive law); this resets the interaction (to the initial=potential state)
                //! and collider should traverse pendingErase to decide whether 
to delete the interaction completely or keep it potential
                void requestErase(body_id_t id1, body_id_t id2);
@@ -134,7 +134,7 @@
                        method which will be called for every interaction.
                */
                template<class T> void erasePending(const T& t){
-                       FOREACH(const vector<body_id_t>& p, pendingErase){ 
if(t.shouldBeErased(p[0],p[1])) erase(p[0],p[1]); }
+                       FOREACH(const Vector2<body_id_t>& p, pendingErase){ 
if(t.shouldBeErased(p[0],p[1])) erase(p[0],p[1]); }
                        pendingErase.clear();
                }
        private :

Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp     2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/gui/py/_utils.cpp     2009-06-02 22:02:25 UTC (rev 1788)
@@ -316,8 +316,41 @@
        vector<Vector2r> hull=ch2d();
        return simplePolygonArea2d(hull);
 }
+/* Find all interactions deriving from NormalShearInteraction that cross plane 
given by a point and normal
+       (the normal may not be normalized in this case, though) and sum forces 
(both normal and shear) on them.
+       
+       Return a 3-tuple with the components along global x,y,z axes.
 
+       (This could be easily extended to return sum of only normal forces or 
only of shear forces.)
+*/
+python::tuple forcesOnPlane(python::tuple _planePt, python::tuple _normal){
+       Vector3r ret(Vector3r::ZERO), planePt(tuple2vec(_planePt)), 
normal(tuple2vec(_normal));
+       MetaBody* rootBody=Omega::instance().getRootBody().get();
+       FOREACH(const shared_ptr<Interaction>&I, *rootBody->interactions){
+               if(!I->isReal()) continue;
+               NormalShearInteraction* 
nsi=dynamic_cast<NormalShearInteraction*>(I->interactionPhysics.get());
+               if(!nsi) continue;
+               Vector3r pos1,pos2;
+               Dem3DofGeom* 
d3dg=dynamic_cast<Dem3DofGeom*>(I->interactionGeometry.get()); // Dem3DofGeom 
has copy of se3 in itself, otherwise we have to look up the bodies
+               if(d3dg){ pos1=d3dg->se31.position; pos2=d3dg->se32.position; }
+               else{ 
pos1=Body::byId(I->getId1(),rootBody)->physicalParameters->se3.position; 
pos2=Body::byId(I->getId2(),rootBody)->physicalParameters->se3.position; }
+               Real dot1=(pos1-planePt).Dot(normal), 
dot2=(pos2-planePt).Dot(normal);
+               if(dot1*dot2>0) continue; // both interaction points on the 
same side of the plane
+               // if pt1 is on the negative plane side, 
d3dg->normal.Dot(normal)>0, the force is well oriented;
+               // otherwise, reverse its contribution
+               ret+=(dot1<0.?1.:-1.)*(nsi->normalForce+nsi->shearForce);
+       }
+       return vec2tuple(ret);
+}
 
+/* Less general than forcesOnPlane, computes force on plane perpendicular to 
axis, passing through coordinate coord. */
+python::tuple forcesOnCoordPlane(Real coord, int axis){
+       Vector3r planePt(Vector3r::ZERO); planePt[axis]=coord;
+       Vector3r normal(Vector3r::ZERO); normal[axis]=1;
+       return forcesOnPlane(vec2tuple(planePt),vec2tuple(normal));
+}
+
+
 /* Project 3d point into 2d using spiral projection along given axis;
  * the returned tuple is
  *     
@@ -383,6 +416,8 @@
        def("kineticEnergy",Shop__kineticEnergy);
        def("sumBexForces",sumBexForces);
        def("sumBexTorques",sumBexTorques);
+       def("forcesOnPlane",forcesOnPlane);
+       def("forcesOnCoordPlane",forcesOnCoordPlane);
        def("createInteraction",Shop__createExplicitInteraction);
        
def("spiralProject",spiralProject,spiralProject_overloads(args("axis","periodStart","theta0")));
        def("pointInsidePolygon",pointInsidePolygon);

Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py       2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/gui/py/utils.py       2009-06-02 22:02:25 UTC (rev 1788)
@@ -404,42 +404,20 @@
        l=procStatus('VmData'); ll=l.split(); assert(ll[2]=='kB')
        return int(ll[1])
 
-
-
-def xcombine(*seqin):
-       '''returns a generator which returns combinations of argument sequences
-for example xcombine((1,2),(3,4)) returns a generator; calling the next()
-method on the generator will return [1,3], [1,4], [2,3], [2,4] and
-StopIteration exception.  This will not create the whole list of 
-combinations in memory at once.
-
-Source: http://code.activestate.com/recipes/302478/'''
-       def rloop(seqin,comb):
-               '''recursive looping function'''
-               if seqin:                                  # any more sequences 
to process?
-                       for item in seqin[0]:
-                               newcomb=comb+[item]      # add next item to 
current combination
-                               # call rloop w/ remaining seqs, newcomb
-                               for item in rloop(seqin[1:],newcomb):   
-                                       yield item                # seqs and 
newcomb
-               else:                                              # processing 
last sequence
-                       yield comb                                # comb 
finished, add to list
-       return rloop(seqin,[])
-
-
 def regularSphereOrthoPack(center,extents,radius,gap,**kw):
        """Return set of spheres regularly spaced in either a box or sphere 
centered around center.
        If extents is a number, it is taken for sphere radius; if it is a 
sequence, it is 3 extents of the box.
        Created spheres will have given radius and will be separated by gap 
space.
        """
        from numpy import arange; from math import sqrt
+       import itertools
        ret=[]
        try: # extents is a single number, do sphere
                doSphere=True; dim=float(extents),float(extents),float(extents)
        except TypeError: # extents is a list, do box
                doSphere=False; dim=extents
        xx,yy,zz=[arange(center[i]-dim[i],center[i]+dim[i],2*radius+gap) for i 
in 0,1,2]
-       for xyz in xcombine(xx,yy,zz):
+       for xyz in itertools.product(xx,yy,zz):
                if doSphere and sqrt(sum([(xyz[i]-center[i])**2 for i in 
0,1,2]))>extents: continue
                ret+=[sphere(xyz,radius=radius,**kw)]
        return ret
@@ -461,7 +439,7 @@
        dim=aabbDim(); axis=dim.index(max(dim))
        import numpy
        areas=[approxSectionArea(coord,axis) for coord in 
numpy.linspace(mm[axis],mx[axis],num=10)[1:-1]]
-       negIds,posIds=negPosExtremeIds(axis=axis)
+       negIds,posIds=negPosExtremeIds(axis=axis,distFactor=2.2)
        return {'negIds':negIds,'posIds':posIds,'axis':axis,'area':min(areas)}
 
 

Modified: trunk/lib/serialization/Archive.tpp
===================================================================
--- trunk/lib/serialization/Archive.tpp 2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/lib/serialization/Archive.tpp 2009-06-02 22:02:25 UTC (rev 1788)
@@ -48,6 +48,10 @@
                        typeid(Type)==typeid(Vector2f)          ||
                        typeid(Type)==typeid(Vector2d)          ||
                        typeid(Type)==typeid(Vector2<long double>)              
||
+                       typeid(Type)==typeid(Vector2<signed int>)               
||
+                       typeid(Type)==typeid(Vector2<unsigned int>)             
||
+                       typeid(Type)==typeid(Vector2<signed long>)              
||
+                       typeid(Type)==typeid(Vector2<unsigned long>)            
||
                        typeid(Type)==typeid(Vector3f)          ||
                        typeid(Type)==typeid(Vector3d)          ||
                        typeid(Type)==typeid(Vector3<long double>)              
||

Modified: trunk/pkg/dem/ConcretePM.cpp
===================================================================
--- trunk/pkg/dem/ConcretePM.cpp        2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/pkg/dem/ConcretePM.cpp        2009-06-02 22:02:25 UTC (rev 1788)
@@ -116,13 +116,14 @@
 }
 
 
-
 /********************** Law2_Dem3DofGeom_CpmPhys_Cpm 
****************************/
 
 Real Law2_Dem3DofGeom_CpmPhys_Cpm::minStrain_moveBody2=1.; /* deactivated if > 
0 */
 Real Law2_Dem3DofGeom_CpmPhys_Cpm::yieldLogSpeed=1.;
 Real Law2_Dem3DofGeom_CpmPhys_Cpm::yieldEllipseShift=0.;
-Real Law2_Dem3DofGeom_CpmPhys_Cpm::omegaThreshold=0.;
+Real Law2_Dem3DofGeom_CpmPhys_Cpm::omegaThreshold=1.;
+Real Law2_Dem3DofGeom_CpmPhys_Cpm::epsSoft=0.;
+Real Law2_Dem3DofGeom_CpmPhys_Cpm::relKnSoft=.5;
 
 void Law2_Dem3DofGeom_CpmPhys_Cpm::go(shared_ptr<InteractionGeometry>& _geom, 
shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody){
        //timingDeltas->start();
@@ -130,10 +131,12 @@
        CpmPhys* BC=static_cast<CpmPhys*>(_phys.get());
 
        // shorthands
-       Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& 
kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const Real& E(BC->E); const 
Real& undamagedCohesion(BC->undamagedCohesion); const Real& 
tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& 
crossSection(BC->crossSection); const Real& 
omegaThreshold(Law2_Dem3DofGeom_CpmPhys_Cpm::omegaThreshold); const Real& 
epsCrackOnset(BC->epsCrackOnset); Real& 
relResidualStrength(BC->relResidualStrength); const Real& 
dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); 
const bool& neverDamage(BC->neverDamage); const Real& dmgTau(BC->dmgTau); const 
Real& plTau(BC->plTau); const bool& isCohesive(BC->isCohesive);
+       Real& epsN(BC->epsN); Real& epsNPl(BC->epsNPl); Vector3r& 
epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const 
Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const 
Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& 
crossSection(BC->crossSection); const Real& 
omegaThreshold(Law2_Dem3DofGeom_CpmPhys_Cpm::omegaThreshold); const Real& 
epsCrackOnset(BC->epsCrackOnset); Real& 
relResidualStrength(BC->relResidualStrength); const Real& 
dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); 
const bool& neverDamage(BC->neverDamage); const Real& dmgTau(BC->dmgTau); const 
Real& plTau(BC->plTau); const bool& isCohesive(BC->isCohesive);
        Real& omega(BC->omega); Real& sigmaN(BC->sigmaN);  Vector3r& 
sigmaT(BC->sigmaT); Real& Fn(BC->Fn); Vector3r& Fs(BC->Fs); // for python access
        const Real& yieldLogSpeed(Law2_Dem3DofGeom_CpmPhys_Cpm::yieldLogSpeed); 
const int& yieldSurfType(Law2_Dem3DofGeom_CpmPhys_Cpm::yieldSurfType);
        const Real& 
yieldEllipseShift(Law2_Dem3DofGeom_CpmPhys_Cpm::yieldEllipseShift); 
+       const Real& epsSoft(Law2_Dem3DofGeom_CpmPhys_Cpm::epsSoft); 
+       const Real& relKnSoft(Law2_Dem3DofGeom_CpmPhys_Cpm::relKnSoft); 
 
        #define YADE_VERIFY(condition) if(!(condition)){LOG_FATAL("Verification 
`"<<#condition<<"' failed!"); throw;}
        

Modified: trunk/pkg/dem/ConcretePM.hpp
===================================================================
--- trunk/pkg/dem/ConcretePM.hpp        2009-05-31 10:09:14 UTC (rev 1787)
+++ trunk/pkg/dem/ConcretePM.hpp        2009-06-02 22:02:25 UTC (rev 1788)
@@ -120,13 +120,15 @@
                        isoPrestress;
                /*! Up to now maximum normal strain (semi-norm), non-decreasing 
in time. */
                Real kappaD;
+               //! normal plastic strain (initially zero)
+               Real epsNPl;
                /*! Transversal strain (perpendicular to the contact axis) */
                Real epsTrans;
                /*! if not cohesive, interaction is deleted when distance is 
greater than zero. */
                bool isCohesive;
                /*! the damage evlution function will always return virgin 
state */
                bool neverDamage;
-               /*! cummulative plastic strain measure (scalar) on this contact 
*/
+               /*! cummulative shear plastic strain measure (scalar) on this 
contact */
                Real epsPlSum;
                //! debugging, to see convergence rate
                static long cummBetaIter, cummBetaCount;
@@ -142,7 +144,7 @@
 
 
 
-               CpmPhys(): NormalShearInteraction(),E(0), G(0), 
tanFrictionAngle(0), undamagedCohesion(0), crossSection(0), dmgTau(-1), 
dmgRateExp(0), dmgStrain(0), plTau(-1), plRateExp(0), isoPrestress(0.), 
kappaD(0.), epsTrans(0.), epsPlSum(0.) { createIndex(); epsT=Vector3r::ZERO; 
isCohesive=false; neverDamage=false; omega=0; Fn=0; Fs=Vector3r::ZERO; 
epsPlSum=0; dmgOverstress=0; }
+               CpmPhys(): NormalShearInteraction(),E(0), G(0), 
tanFrictionAngle(0), undamagedCohesion(0), crossSection(0), dmgTau(-1), 
dmgRateExp(0), dmgStrain(0), plTau(-1), plRateExp(0), isoPrestress(0.), 
kappaD(0.), epsNPl(0.), epsTrans(0.), epsPlSum(0.) { createIndex(); 
epsT=Vector3r::ZERO; isCohesive=false; neverDamage=false; omega=0; Fn=0; 
Fs=Vector3r::ZERO; epsPlSum=0; dmgOverstress=0; }
                virtual ~CpmPhys();
 
                REGISTER_ATTRIBUTES(NormalShearInteraction,
@@ -165,6 +167,7 @@
                        (cummBetaCount)
 
                        (kappaD)
+                       (epsNPl)
                        (neverDamage)
                        (epsT)
                        (epsTrans)
@@ -256,11 +259,15 @@
                static Real omegaThreshold;
                //! HACK: limit strain on some contacts by moving body #2 in 
the contact; only if refR1<0 (facet); deactivated if > 0
                static Real minStrain_moveBody2;
+               //! Strain at which softening in compression starts (set to 0. 
(default) or positive value to deactivate)
+               static Real epsSoft;
+               //! Relative rigidity of the softening branch in compression 
(0=perfect elastic-plastic, 1=no softening, >1=hardening)
+               static Real relKnSoft;
                Law2_Dem3DofGeom_CpmPhys_Cpm(): logStrain(false), 
yieldSurfType(0) { /*timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);*/ 
}
                void go(shared_ptr<InteractionGeometry>& _geom, 
shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody);
        FUNCTOR2D(Dem3DofGeom,CpmPhys);
        REGISTER_CLASS_AND_BASE(Law2_Dem3DofGeom_CpmPhys_Cpm,ConstitutiveLaw);
-       
REGISTER_ATTRIBUTES(ConstitutiveLaw,(logStrain)(yieldSurfType)(yieldLogSpeed)(yieldEllipseShift)(minStrain_moveBody2)(omegaThreshold));
+       
REGISTER_ATTRIBUTES(ConstitutiveLaw,(logStrain)(yieldSurfType)(yieldLogSpeed)(yieldEllipseShift)(minStrain_moveBody2)(omegaThreshold)(epsSoft)(relKnSoft));
        DECLARE_LOGGER;
 };
 REGISTER_SERIALIZABLE(Law2_Dem3DofGeom_CpmPhys_Cpm);

Modified: trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp  2009-05-31 
10:09:14 UTC (rev 1787)
+++ trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp  2009-06-02 
22:02:25 UTC (rev 1788)
@@ -81,7 +81,7 @@
                        
YADE_CAST<ParticleParameters*>(b->physicalParameters.get())->velocity[axis]=pNormalized*(v1-v0)+v0;
                }
        }
-       
stressUpdateInterval=max(1,(int)(1e-5/(abs(strainRate)*Omega::instance().getTimeStep())));
+       
stressUpdateInterval=min(1000,max(1,(int)(1e-5/(abs(strainRate)*Omega::instance().getTimeStep()))));
        LOG_INFO("Stress will be updated every "<<stressUpdateInterval<<" 
steps.");
 
        /* if we have default (<0) crossSectionArea, try to get it from root's 
AABB;
@@ -133,13 +133,17 @@
                }
        }
        if(asymmetry==0) dAX*=.5; // apply half on both sides if straining 
symetrically
-       for(size_t i=0; i<negIds.size(); i++){
-               if(asymmetry==0 || asymmetry==-1 /* for +1, don't move*/) 
negCoords[i]-=dAX;
-               axisCoord(negIds[i])=negCoords[i]; // update current position
+       if(asymmetry!=1){
+               for(size_t i=0; i<negIds.size(); i++){
+                       negCoords[i]-=dAX;
+                       axisCoord(negIds[i])=negCoords[i]; // update current 
position
+               }
        }
-       for(size_t i=0; i<posIds.size(); i++){
-               if(asymmetry==0 || asymmetry==1 /* for -1, don't move */) 
posCoords[i]+=dAX;
-               axisCoord(posIds[i])=posCoords[i];
+       if(asymmetry!=-1){
+               for(size_t i=0; i<posIds.size(); i++){
+                       posCoords[i]+=dAX;
+                       axisCoord(posIds[i])=posCoords[i];
+               }
        }
 
        Real axialLength=axisCoord(posIds[0])-axisCoord(negIds[0]);


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : yade-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to