yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #01284
[svn] r1788 - in trunk: core gui/py lib/serialization pkg/dem pkg/dem/Engine/StandAloneEngine
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]);
Follow ups