Author: eudoxos
Date: 2009-05-31 12:09:14 +0200 (Sun, 31 May 2009)
New Revision: 1787
Added:
trunk/lib/computational-geometry/Hull2d.hpp
Modified:
trunk/core/InteractionContainer.cpp
trunk/examples/concrete/pack/mk-pack.py
trunk/gui/py/_utils.cpp
trunk/gui/py/eudoxos.py
trunk/gui/py/utils.py
trunk/gui/py/yadeControl.cpp
trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
trunk/pkg/dem/ConcretePM.cpp
trunk/pkg/dem/ConcretePM.hpp
trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp
Log:
1. Syntax fixes in ConcretePM model
2. Interactions will be deleted also if the ye4xist, but geometry functor fails
(returns false)
3. Add utils.approxSectionArea, utils.spheresFromFileUnixial (get some
parameters useful for uniaxial tests from the sphere packing, such as
cross-section, principal axis, etc)
4. Add lib/computational-geometry/Hull2d.hpp for computing convex hull in 2d
using Graham scan algorithm (I know it is in CGAL already, but I don't want to
depend on that commercial stuff)
5. Remove some unused stuff from utils.
Modified: trunk/core/InteractionContainer.cpp
===================================================================
--- trunk/core/InteractionContainer.cpp 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/core/InteractionContainer.cpp 2009-05-31 10:09:14 UTC (rev 1787)
@@ -12,7 +12,9 @@
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);
- boost::mutex::scoped_lock lock(pendingEraseMutex);
+ #ifdef YADE_OPENMP
+ boost::mutex::scoped_lock lock(pendingEraseMutex);
+ #endif
pendingErase.push_back(v);
}
Modified: trunk/examples/concrete/pack/mk-pack.py
===================================================================
--- trunk/examples/concrete/pack/mk-pack.py 2009-05-29 14:35:22 UTC (rev
1786)
+++ trunk/examples/concrete/pack/mk-pack.py 2009-05-31 10:09:14 UTC (rev
1787)
@@ -12,7 +12,7 @@
cutoffRound=2
tt=TriaxialTest(
- numberOfGrains=500,
+ numberOfGrains=5000,
radiusMean=3e-4,
# this is just size ratio if radiusMean is specified
# if you comment out the line above, it will be the corner (before
compaction) and radiusMean will be set accordingly
@@ -44,7 +44,7 @@
ext=utils.aabbExtrema()
rSphere=tt['radiusMean']
-outFile=tempfile.NamedTemporaryFile(delete=False)
+outFile=tempfile.NamedTemporaryFile(delete=False).name
if cylAxis<0: # box-shaped packing
aabbMin,aabbMax=tuple([ext[0][i]+rSphere*cutoffFlat for i in
0,1,2]),tuple([ext[1][i]-rSphere*cutoffFlat for i in 0,1,2])
@@ -67,7 +67,7 @@
return True
nSpheres=utils.spheresToFile(outFile,consider=isInCyl)
-outFile2='pack-%d-%s.sphere'%(nSpheres,'box' if cylAxis<0 else 'cyl')
+outFile2='pack-%d-%s.spheres'%(nSpheres,'box' if cylAxis<0 else 'cyl')
shutil.move(outFile,outFile2)
print nSpheres,'spheres written to',outFile2
quit()
Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/gui/py/_utils.cpp 2009-05-31 10:09:14 UTC (rev 1787)
@@ -8,6 +8,7 @@
#include<yade/pkg-dem/DemXDofGeom.hpp>
#include<yade/pkg-dem/SimpleViscoelasticBodyParameters.hpp>
#include<yade/pkg-common/NormalShearInteractions.hpp>
+#include<yade/lib-computational-geometry/Hull2d.hpp>
#include<cmath>
#include<numpy/ndarrayobject.h>
@@ -284,7 +285,39 @@
return inside;
}
+/* Compute area of convex hull when when taking (swept) spheres crossing the
plane at coord, perpendicular to axis.
+ All spheres that touch the plane are projected as hexagons on their
circumference to the plane.
+ Convex hull from this cloud is computed.
+ The area of the hull is returned.
+
+*/
+Real approxSectionArea(Real coord, int axis){
+ std::list<Vector2r> cloud;
+ if(axis<0 || axis>2) throw invalid_argument("Axis must be ∈ {0,1,2}");
+ const int ax1=(axis+1)%3, ax2=(axis+2)%3;
+ const Real sqrt3=sqrt(3);
+ Vector2r mm(-10.,0),mx(0,0);
+ FOREACH(const shared_ptr<Body>& b,
*Omega::instance().getRootBody()->bodies){
+ Sphere* s=dynamic_cast<Sphere*>(b->geometricalModel.get());
+ if(!s) continue;
+ const Vector3r& pos(b->physicalParameters->se3.position); const
Real r(s->radius);
+ if((pos[axis]>coord && (pos[axis]-r)>coord) || (pos[axis]<coord
&& (pos[axis]+r)<coord)) continue;
+ Vector2r c(pos[ax1],pos[ax2]);
+ cloud.push_back(c+Vector2r(r,0));
cloud.push_back(c+Vector2r(-r,0));
+ cloud.push_back(c+Vector2r( r/2., sqrt3*r));
cloud.push_back(c+Vector2r( r/2.,-sqrt3*r));
+ cloud.push_back(c+Vector2r(-r/2., sqrt3*r));
cloud.push_back(c+Vector2r(-r/2.,-sqrt3*r));
+ if(mm[0]==-10.){ mm=c, mx=c;}
+ mm=Vector2r(min(c[0]-r,mm[0]),min(c[1]-r,mm[1]));
+ mx=Vector2r(max(c[0]+r,mx[0]),max(c[1]+r,mx[1]));
+ }
+ if(cloud.size()==0) return 0;
+ ConvexHull2d ch2d(cloud);
+ vector<Vector2r> hull=ch2d();
+ return simplePolygonArea2d(hull);
+}
+
+
/* Project 3d point into 2d using spiral projection along given axis;
* the returned tuple is
*
@@ -338,6 +371,7 @@
def("aabbExtrema",aabbExtrema,aabbExtrema_overloads(args("cutoff","centers"),"Return
coordinates of box enclosing all bodies\n centers: do not take sphere radii in
account, only their centroids (default=False)\n cutoff: 0-1 number by which the
box will be scaled around its center (default=0)"));
def("ptInAABB",ptInAABB,"Return True/False whether the point (3-tuple)
p is within box given by its min (3-tuple) and max (3-tuple) corners");
def("negPosExtremeIds",negPosExtremeIds,negPosExtremeIds_overloads(args("axis","distFactor"),"Return
list of ids for spheres (only) that are on extremal ends of the specimen along
given axis; distFactor multiplies their radius so that sphere that do not touch
the boundary coordinate can also be returned."));
+ def("approxSectionArea",approxSectionArea,"Compute area of convex hull
when when taking (swept) spheres crossing the plane at coord, perpendicular to
axis.");
def("coordsAndDisplacements",coordsAndDisplacements,coordsAndDisplacements_overloads(args("AABB"),"Return
tuple of 2 same-length lists for coordinates and displacements (coordinate
minus reference coordinate) along given axis (1st arg); if the
AABB=((x_min,y_min,z_min),(x_max,y_max,z_max)) box is given, only bodies within
this box will be considered."));
def("setRefSe3",setRefSe3,"Set reference positions and orientation of
all bodies equal to their current ones.");
def("interactionAnglesHistogram",interactionAnglesHistogram,interactionAnglesHistogram_overloads(args("axis","mask","bins","aabb")));
Modified: trunk/gui/py/eudoxos.py
===================================================================
--- trunk/gui/py/eudoxos.py 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/gui/py/eudoxos.py 2009-05-31 10:09:14 UTC (rev 1787)
@@ -74,7 +74,7 @@
ph=o.interactions.nth(0).phys # some params are the same everywhere
material.append("%g %g"%(ph['E'],ph['G']))
- material.append("%g %g %g
%g"%(ph['epsCrackOnset'],ph['epsFracture'],1e50,ph['xiShear']))
+ material.append("%g %g %g
%g"%(ph['epsCrackOnset'],ph['epsFracture'],1e50,0.0))
material.append("%g
%g"%(ph['undamagedCohesion'],ph['tanFrictionAngle']))
# need strainer for getting bodies in positive/negative boundary
@@ -174,7 +174,7 @@
f.write("SimpleCS 1 thick 1.0 width 1.0\n")
# material
ph=inters[0].phys
- f.write("CohInt 1 kn %g ks %g e0 %g ef %g c 0. ksi %g coh %g tanphi %g
damchartime %g damrateexp %g plchartime %g plrateexp %g d
1.0\n"%(ph['E'],ph['G'],ph['epsCrackOnset'],ph['epsFracture'],ph['xiShear'],ph['undamagedCohesion'],ph['tanFrictionAngle'],ph['dmgTau'],ph['dmgRateExp'],ph['plTau'],ph['plRateExp']))
+ f.write("CohInt 1 kn %g ks %g e0 %g ef %g c 0. ksi %g coh %g tanphi %g
damchartime %g damrateexp %g plchartime %g plrateexp %g d
1.0\n"%(ph['E'],ph['G'],ph['epsCrackOnset'],ph['epsFracture'],0.0,ph['undamagedCohesion'],ph['tanFrictionAngle'],ph['dmgTau'],ph['dmgRateExp'],ph['plTau'],ph['plRateExp']))
# boundary conditions
f.write('BoundaryCondition 1 loadTimeFunction 1 prescribedvalue 0.0\n')
f.write('BoundaryCondition 2 loadTimeFunction 1 prescribedvalue
1.e-4\n')
Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/gui/py/utils.py 2009-05-31 10:09:14 UTC (rev 1787)
@@ -4,8 +4,6 @@
#
# 2008 © Václav Šmilauer <[email protected]>
-#from yade._utils import *
-
import math,random
from yade.wrapper import *
try: # use psyco if available
@@ -16,16 +14,6 @@
# c++ implementations for performance reasons
from yade._utils import *
-def resetEngineClocks():
- for e in O.engines: e.execTime=0
-def engineClockStats():
- tSum=sum([e.execTime for e in O.engines])
- for e in O.engines:
- print
e.name.ljust(30),(str(e.execTime/1000)+'ms').rjust(15),'%6.2f%%'%(e.execTime*100./tSum)
- print '='*53
- print 'TOTAL'.ljust(30),(str(tSum/1000)+'ms').rjust(15),'100.00%'
-
-
def saveVars(mark='',loadNow=False,**kw):
"""Save passed variables into the simulation so that it can be
recovered when the simulation is loaded again.
@@ -381,44 +369,6 @@
dictParams.update(dictDefaults); saveVars('table',**dictParams)
return len(tagsParams)
-
-def
basicDEMEngines(interPhysics='SimpleElasticRelationships',constitutiveLaw='ElasticContactLaw',gravity=None,damping=.4):
- """Set basic set of DEM engines and initializers.
-
- interPhysics and constitutiveLaw specify class of respective engines to
use instead of defaults.
-
- Gravity can be list or tuple to specify numeric value, it can also be
an object that will be inserted into
- engines, however. By default, no gravity is applied.
- """
- O.initializers=[
-
MetaEngine('BoundingVolumeMetaEngine',[EngineUnit('InteractingSphere2AABB'),EngineUnit('InteractingBox2AABB'),EngineUnit('InteractingFacet2AABB'),EngineUnit('MetaInteractingGeometry2AABB')])
- ]
- O.engines=[
- StandAloneEngine('PhysicalActionContainerReseter'),
- MetaEngine('BoundingVolumeMetaEngine',[
- EngineUnit('InteractingSphere2AABB'),
- EngineUnit('InteractingBox2AABB'),
- EngineUnit('InteractingFacet2AABB'),
- EngineUnit('MetaInteractingGeometry2AABB')
- ]),
- StandAloneEngine('PersistentSAPCollider'),
- MetaEngine('InteractionGeometryMetaEngine',[
-
EngineUnit('InteractingSphere2InteractingSphere4SpheresContactGeometry'),
-
EngineUnit('InteractingFacet2InteractingSphere4SpheresContactGeometry'),
-
EngineUnit('InteractingBox2InteractingSphere4SpheresContactGeometry')
- ]),
-
MetaEngine('InteractionPhysicsMetaEngine',[EngineUnit('SimpleElasticRelationships')]),
- StandAloneEngine('ElasticContactLaw'),
- ]
- if gravity:
- if islist(gravity) or istuple(gravity):
-
O.engines=O.engines+[DeusExMachina('GravityEngine',{'gravity':gravity}),]
- else:
- O.engines=O.engines+[gravity]
-
O.engines=O.engines+[DeusExMachina('NewtonsDampedLaw',{'damping':damping}),]
-
-
-
def
ColorizedVelocityFilter(isFilterActivated=True,autoScale=True,minValue=0,maxValue=0,posX=0,posY=0.2,width=0.05,height=0.5,title='Velocity,
m/s'):
f =
DeusExMachina('ColorizedVelocityFilter',{'isFilterActivated':isFilterActivated,'autoScale':autoScale,'minValue':minValue,'maxValue':maxValue,'posX':posX,'posY':posY,'width':width,'height':height,'title':title})
O.engines+=[f]
@@ -494,4 +444,24 @@
ret+=[sphere(xyz,radius=radius,**kw)]
return ret
+def spheresFromFileUniaxial(filename,areaSections=10,**kw):
+ """Load spheres from file, but do some additional work useful for
uniaxial test:
+
+ 1. Find the dimensions that is the longest (uniaxial loading axis)
+ 2. Find the minimum cross-section area of the speciment by examining
several (areaSections)
+ sections perpendicular to axis, computing area of the convex
hull for each one. This will
+ work also for non-prismatic specimen.
+ 3. Find the bodies that are on the negative/positive boundary, to which
the straining condition
+ should be applied.
+ Returns dictionary with keys 'negIds', 'posIds', 'axis', 'area'.
+ """
+ ids=spheresFromFile(filename,**kw)
+ mm,mx=aabbExtrema()
+ 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)
+ return {'negIds':negIds,'posIds':posIds,'axis':axis,'area':min(areas)}
+
+
Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/gui/py/yadeControl.cpp 2009-05-31 10:09:14 UTC (rev 1787)
@@ -316,6 +316,7 @@
NONPOD_ATTRIBUTE_ACCESS(geom,pyInteractionGeometry,interactionGeometry);
NONPOD_ATTRIBUTE_ACCESS(phys,pyInteractionPhysics,interactionPhysics);
/* shorthands */ unsigned id1_get(void){ensureAcc(); return
proxee->getId1();} unsigned id2_get(void){ensureAcc(); return proxee->getId2();}
+ bool isReal_get(void){ensureAcc(); return proxee->isReal(); }
BASIC_PY_PROXY_TAIL;
BASIC_PY_PROXY_HEAD(pyBody,Body)
@@ -807,7 +808,8 @@
.add_property("phys",&pyInteraction::phys_get,&pyInteraction::phys_set)
.add_property("geom",&pyInteraction::geom_get,&pyInteraction::geom_set)
.add_property("id1",&pyInteraction::id1_get)
- .add_property("id2",&pyInteraction::id2_get);
+ .add_property("id2",&pyInteraction::id2_get)
+ .add_property("isReal",&pyInteraction::isReal_get);
BASIC_PY_PROXY_WRAPPER(pyFileGenerator,"Preprocessor")
.def("generate",&pyFileGenerator::generate)
Added: trunk/lib/computational-geometry/Hull2d.hpp
===================================================================
--- trunk/lib/computational-geometry/Hull2d.hpp 2009-05-29 14:35:22 UTC (rev
1786)
+++ trunk/lib/computational-geometry/Hull2d.hpp 2009-05-31 10:09:14 UTC (rev
1787)
@@ -0,0 +1,71 @@
+// 2009 © Václav Šmilauer <[email protected]>
+
+
+/*! Computing convex hull of a 2d cloud of points passed to the constructor,
+ using Graham scan algorithm.
+
+ Use the operator() to launch computation and get the hull as
std::list<Vector2r>.
+
+ The source http://marknelson.us/2007/08/22/convex/ is gratefully
acknowledged.
+ Look there for detailed description and more information.
+*/
+class ConvexHull2d{
+ list<Vector2r> raw_points, lower_partition_points,
upper_partition_points, hull;
+ Vector2r left, right;
+ static Real direction(const Vector2r& p0, const Vector2r& p1, const
Vector2r& p2) {
+ return
((p0[0]-p1[0])*(p2[1]-p1[1]))-((p2[0]-p1[0])*(p0[1]-p1[1]));
+ }
+ struct Vector2r_xComparator{
+ bool operator()(const Vector2r& p1, const Vector2r& p2){return
p1[0]<p2[0];}
+ };
+
+ void partition_points(){
+ raw_points.sort(Vector2r_xComparator());
+ left=raw_points.front(); raw_points.pop_front();
+ right=raw_points.back(); raw_points.pop_back();
+ FOREACH(const Vector2r& p, raw_points){
+ if(direction(left,right,p)<0)
upper_partition_points.push_back(p);
+ else lower_partition_points.push_back(p);
+ }
+ }
+ vector<Vector2r> build_half_hull(list<Vector2r>& in, int factor){
+ vector<Vector2r> out;
+ in.push_back(right); out.push_back(left);
+ while(in.size()>0){
+ out.push_back(in.front()); in.pop_front();
+ while(out.size()>=3){
+ size_t end=out.size()-1;
+
if(factor*direction(out[end-2],out[end],out[end-1])<=0)
out.erase(out.begin()+end-1);
+ else break;
+ }
+ }
+ return out;
+ }
+ public:
+ ConvexHull2d(const list<Vector2r>&
pts){raw_points.assign(pts.begin(),pts.end());};
+ ConvexHull2d(const vector<Vector2r>&
pts){raw_points.assign(pts.begin(),pts.end());};
+ vector<Vector2r> operator()(void){
+ partition_points();
+ vector<Vector2r>
lower_hull=build_half_hull(lower_partition_points,1);
+ vector<Vector2r>
upper_hull=build_half_hull(upper_partition_points,-1);
+ vector<Vector2r> ret;
ret.reserve(lower_hull.size()+upper_hull.size()-2);
+ for(size_t i=upper_hull.size()-1; i>0; i--)
ret.push_back(upper_hull[i]);
+ size_t lsize=lower_hull.size();
+ for(size_t i=0; i<lsize-1; i++) ret.push_back(lower_hull[i]);
+ return ret;
+ }
+};
+
+/*! Compute area of a simple 2d polygon, using the Surveyor's formula.
+ http://en.wikipedia.org/wiki/Polygon
+
+ The first and last points shouldn't be given twice.
+*/
+Real simplePolygonArea2d(vector<Vector2r> P){
+ Real ret=0.; size_t n=P.size();
+ for(size_t i=0; i<n-1; i++) { ret+=P[i][0]*P[i+1][1]-P[i+1][0]*P[i][1];}
+ ret+=P[n-1][0]*P[0][1]-P[0][0]*P[n-1][1];
+ return abs(ret/2.);
+}
+
+
Modified: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
2009-05-31 10:09:14 UTC (rev 1787)
@@ -53,8 +53,12 @@
const shared_ptr<Body>&
b2=Body::byId(I->getId2(),rootBody);
assert(I->functorCache.geom);
+ bool wasReal=I->isReal();
bool
geomCreated=I->functorCache.geom->go(b1->interactingGeometry,b2->interactingGeometry,b1->physicalParameters->se3,
b2->physicalParameters->se3,I);
- if(!geomCreated) continue;
+ if(!geomCreated){
+ if(wasReal)
rootBody->interactions->requestErase(I->getId1(),I->getId2()); // fully created
interaction without geometry is reset and perhaps erased in the next step
+ continue; // in any case don't care about this
one anymore
+ }
// InteractionPhysicsMetaEngine
if(!I->functorCache.phys){
@@ -80,10 +84,14 @@
const shared_ptr<Body>&
b1=Body::byId(I->getId1(),rootBody);
const shared_ptr<Body>&
b2=Body::byId(I->getId2(),rootBody);
// InteractionGeometryMetaEngine
+ bool wasReal=I->isReal();
bool geomCreated =
b1->interactingGeometry &&
b2->interactingGeometry && // some bodies do not have interactingGeometry
geomDispatcher->operator()(b1->interactingGeometry, b2->interactingGeometry,
b1->physicalParameters->se3, b2->physicalParameters->se3,I);
- if(!geomCreated) continue;
+ if(!geomCreated){
+ if(wasReal)
*rootBody->interactions->requestErase(I->getId1(),I->getId2());
+ continue;
+ }
// InteractionPhysicsMetaEngine
// geom may have swapped bodies, get bodies again
physDispatcher->operator()(Body::byId(I->getId1(),rootBody)->physicalParameters,
Body::byId(I->getId2(),rootBody)->physicalParameters,I);
Modified: trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
2009-05-31 10:09:14 UTC (rev 1787)
@@ -58,14 +58,17 @@
const long size=ncb->transientInteractions->size();
#pragma omp parallel for
for(long i=0; i<size; i++){
- const shared_ptr<Interaction>&
interaction=(*ncb->transientInteractions)[i];
+ const shared_ptr<Interaction>&
I=(*ncb->transientInteractions)[i];
#else
- FOREACH(const shared_ptr<Interaction>& interaction,
*ncb->interactions){
+ FOREACH(const shared_ptr<Interaction>& I, *ncb->interactions){
#endif
- const shared_ptr<Body>&
b1=(*bodies)[interaction->getId1()];
- const shared_ptr<Body>&
b2=(*bodies)[interaction->getId2()];
- b1->interactingGeometry && b2->interactingGeometry &&
// some bodies do not have interactingGeometry
- operator()(b1->interactingGeometry,
b2->interactingGeometry, b1->physicalParameters->se3,
b2->physicalParameters->se3, interaction);
+ const shared_ptr<Body>& b1=(*bodies)[I->getId1()];
+ const shared_ptr<Body>& b2=(*bodies)[I->getId2()];
+ bool wasReal=I->isReal();
+ if (!b1->interactingGeometry ||
!b2->interactingGeometry) { assert(!wasReal); continue; } // some bodies do not
have interactingGeometry
+ bool geomCreated=operator()(b1->interactingGeometry,
b2->interactingGeometry, b1->physicalParameters->se3,
b2->physicalParameters->se3, I);
+ // reset && erase interaction that existed but now has
no geometry anymore
+ if(wasReal && !geomCreated){
ncb->interactions->requestErase(I->getId1(),I->getId2()); }
}
}
Modified: trunk/pkg/dem/ConcretePM.cpp
===================================================================
--- trunk/pkg/dem/ConcretePM.cpp 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/pkg/dem/ConcretePM.cpp 2009-05-31 10:09:14 UTC (rev 1787)
@@ -164,14 +164,14 @@
CPM_MATERIAL_MODEL
#else
// very simplified version of the constitutive law
- kappaD=max(max(0,epsN),kappaD); // internal variable, max
positive strain (non-decreasing)
+ kappaD=max(max(0.,epsN),kappaD); // internal variable, max
positive strain (non-decreasing)
omega=isCohesive?funcG(kappaD,epsCrackOnset,epsFracture,neverDamage):1.; //
damage variable (non-decreasing, as funcG is also non-decreasing)
sigmaN=(1-(epsN>0?omega:0))*E*epsN; // damage taken in account
in tension only
sigmaT=G*epsT; // trial stress
Real
yieldSigmaT=max((Real)0.,undamagedCohesion*(1-omega)-sigmaN*tanFrictionAngle);
// Mohr-Coulomb law with damage
if(sigmaT.SquaredLength()>yieldSigmaT*yieldSigmaT){
sigmaT*=yieldSigmaT/sigmaT.Length(); // stress return
- epsPlSum+=rT*contGeom->slipToStrainTMax(rT/G); //
adjust strain
+
epsPlSum+=yieldSigmaT*contGeom->slipToStrainTMax(yieldSigmaT/G); // adjust
strain
}
relResidualStrength=isCohesive?(kappaD<epsCrackOnset?1.:(1-omega)*(kappaD)/epsCrackOnset):0;
#endif
Modified: trunk/pkg/dem/ConcretePM.hpp
===================================================================
--- trunk/pkg/dem/ConcretePM.hpp 2009-05-29 14:35:22 UTC (rev 1786)
+++ trunk/pkg/dem/ConcretePM.hpp 2009-05-31 10:09:14 UTC (rev 1787)
@@ -210,7 +210,7 @@
// init to signaling_NaN to force crash if not
initialized (better than unknowingly using garbage values)
sigmaT=epsCrackOnset=relDuctility=G_over_E=std::numeric_limits<Real>::signaling_NaN();
neverDamage=false;
- cohesiveThresholdIter=-1;
+ cohesiveThresholdIter=10;
dmgTau=-1; dmgRateExp=0; plTau=-1; plRateExp=-1;
isoPrestress=0;
}
Modified: trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp
===================================================================
--- trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp 2009-05-29
14:35:22 UTC (rev 1786)
+++ trunk/pkg/dem/Engine/StandAloneEngine/UniaxialStrainer.cpp 2009-05-31
10:09:14 UTC (rev 1787)
@@ -81,7 +81,7 @@
YADE_CAST<ParticleParameters*>(b->physicalParameters.get())->velocity[axis]=pNormalized*(v1-v0)+v0;
}
}
-
stressUpdateInterval=max(1,(int)(2e-5/(abs(strainRate)*Omega::instance().getTimeStep())));
+
stressUpdateInterval=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;
_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help : https://help.launchpad.net/ListHelp