yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #02708
[Branch ~yade-dev/yade/trunk] Rev 1902: 1. Remove Scene::{cellMin,cellMax}, use just Scene::cellSize; update all related code and scripts
------------------------------------------------------------
revno: 1902
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Tue 2009-12-15 10:41:07 +0100
message:
1. Remove Scene::{cellMin,cellMax}, use just Scene::cellSize; update all related code and scripts
2. Change python interface: Omega.periodicCell=Vector3 (only size, no more min/max)
3. Add (not yet used) core/Cell.hpp header. Will be accessible as Scene::cell, once used.
added:
core/Cell.hpp
modified:
core/Interaction.hpp
core/Scene.cpp
core/Scene.hpp
examples/concrete/periodic.py
examples/concrete/uniax.py
gui/qt3/GLViewer.cpp
pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp
pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp
pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp
pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp
pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp
pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp
pkg/dem/DataClass/SpherePack.cpp
pkg/dem/Engine/GlobalEngine/NewtonIntegrator.cpp
pkg/dem/Engine/GlobalEngine/NewtonIntegrator.hpp
pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp
py/pack.py
py/yadeWrapper/yadeWrapper.cpp
scripts/test/pack-cloud.py
scripts/test/periodic-compress.py
scripts/test/periodic-grow.py
scripts/test/periodic-simple.py
scripts/test/periodic-triax.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 'core/Cell.hpp'
--- core/Cell.hpp 1970-01-01 00:00:00 +0000
+++ core/Cell.hpp 2009-12-15 09:41:07 +0000
@@ -0,0 +1,52 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx>
+#include<yade/lib-base/yadeWm3Extra.hpp>
+
+/*! Periodic cell parameters and routines. Usually instantiated as Scene::cell.
+
+The cell has size and skew, which are independent.
+
+*/
+class Cell{
+ public:
+ Vector3r size;
+ Vector3r skew;
+ Vector3r refSize;
+
+ // caches
+ Vector3r _skewAngle;
+ Vector3r _skewSine;
+ Matrix3r _skewTrsf;
+ Matrix3r _unskewTrsf;
+ // should be called before every step
+ void updateCache(){
+ for(int i=0; i<3; i++) {
+ _skewAngle[i]=atan(skew[i]);
+ _skewSine[i]=sin(_skewAngle);
+ }
+ _skewTrsf=Matrix3r(1,skew[1],skew[2],skew[0],1,skew[2],skew[0],skew[1],1);
+ _unskewTrsf=_skewTrst.Inverse();
+ }
+
+ /*! Apply inverse skew on point; to put it inside (unskewed) periodic cell, apply wrapPt on the returned value. */
+ Vector3r unskewPt(Vector3r pt){ return _unskewTrsf*pt; }
+ /*! Wrap number to interval 0â¦sz */
+ Real wrapNum(const Real& x, const Real& sz){
+ Real norm=x/mx; return (norm-floor(norm))*sz;
+ }
+ /*! Wrap number to interval 0â¦sz; store how many intervals were wrapped in period */
+ Real wrapNum(const Real& x, const Real& sz, int& period){
+ Real norm=x/mx; period=(int)floor(norm); return (norm-period[i])*sz[i];
+ }
+ /*! Wrap point to inside the periodic cell; don't compute number of periods wrapped */
+ Vector3r wrapPt(const Vector3r pt){
+ Vector3r ret; for(int i=0;i<3;i++) ret[i]=wrapNum(pt[i],size[i]); return ret;
+ }
+ /*! Wrap point to inside the periodic cell; period will contain by how many cells it was wrapped. */
+ Vector3r wrapPt(const Vector3r pt, Vector3<int>& period){
+ Vector3r ret; for(int i=0; i<3; i++){ ret[i]=wrapNum(pt[i],size[i],period[i]); } return ret;
+ }
+
+ REGISTER_ATTRIBUTES(Serializable,(size)(skew));
+ REGISTER_CLASS_AND_BASE(Cell,Serializable);
+};
+REGISTER_SERIALIZABLE(Cell);
=== modified file 'core/Interaction.hpp'
--- core/Interaction.hpp 2009-12-04 23:07:34 +0000
+++ core/Interaction.hpp 2009-12-15 09:41:07 +0000
@@ -38,7 +38,7 @@
//! NOTE : TriangulationCollider needs this (nothing else)
bool isNeighbor;
- /*! relative distance between bodies, given in (Scene::cellMax-Scene::cellMin) units
+ /*! relative distance between bodies, given in (Scene::cellSize) units
Position of id1 must be incremented by that distance so that there is spatial interaction
NOTE (tricky): cellDist must survive Interaction::reset(), it is only initialized in ctor
=== modified file 'core/Scene.cpp'
--- core/Scene.cpp 2009-12-11 18:10:19 +0000
+++ core/Scene.cpp 2009-12-15 09:41:07 +0000
@@ -44,7 +44,7 @@
dt=1e-8;
selectedBody=-1;
isPeriodic=false;
- cellMin=cellMax=Vector3r::ZERO;
+ cellSize=Vector3r::ZERO;
// FIXME: move SceneShape to core and create it here right away
// shape=shared_ptr<Shape>(new SceneShape);
=== modified file 'core/Scene.hpp'
--- core/Scene.hpp 2009-12-11 18:10:19 +0000
+++ core/Scene.hpp 2009-12-15 09:41:07 +0000
@@ -65,7 +65,7 @@
long stopAtIteration;
Real stopAtVirtTime;
Real stopAtRealTime;
- Vector3r cellMin, cellMax;
+ Vector3r cellSize;
bool isPeriodic;
bool needsInitializers;
@@ -87,8 +87,7 @@
(currentIteration)
(simulationTime)
(stopAtIteration)
- (cellMin)
- (cellMax)
+ (cellSize)
(isPeriodic)
);
REGISTER_CLASS_AND_BASE(Scene,Serializable);
=== modified file 'examples/concrete/periodic.py'
--- examples/concrete/periodic.py 2009-12-11 18:10:19 +0000
+++ examples/concrete/periodic.py 2009-12-15 09:41:07 +0000
@@ -80,7 +80,7 @@
import numpy
avgRadius=numpy.average([r for c,r in sp])
O.bodies.append([utils.sphere(c,r,color=utils.randomColor()) for c,r in sp])
-O.periodicCell=(Vector3(0,0,0),sp.cellSize)
+O.periodicCell=sp.cellSize
axis=2
ax1=(axis+1)%3
ax2=(axis+2)%3
@@ -162,7 +162,6 @@
# FIXME: only temporary, should be .5
minMaxRatio=0.5 if mode=='tension' else 0.5
if extremum==0: return
- cellSize=O.periodicCell[1]-O.periodicCell[0]
print O.tags['id'],mode,strainer['strain'][axis],sigma[-1]
#print 'strain',strainer['strain'],'stress',strainer['stress']
import sys; sys.stdout.flush()
=== modified file 'examples/concrete/uniax.py'
--- examples/concrete/uniax.py 2009-12-11 18:10:19 +0000
+++ examples/concrete/uniax.py 2009-12-15 09:41:07 +0000
@@ -65,7 +65,7 @@
# z-oriented hyperboloid, length 20cm, diameter 10cm, skirt 8cm
# using spheres 7mm of diameter
concreteId=O.materials.append(CpmMat(young=young,frictionAngle=frictionAngle,poisson=poisson,density=4800))
-spheres=pack.randomDensePack(pack.inHyperboloid((0,0,-.5*specimenLength),(0,0,.5*specimenLength),.25*specimenLength,.2*specimenLength),spheresInCell=2000,radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite',material=concreteId)
+spheres=pack.randomDensePack(pack.inHyperboloid((0,0,-.5*specimenLength),(0,0,.5*specimenLength),.25*specimenLength,.17*specimenLength),spheresInCell=2000,radius=sphereRadius,memoizeDb='/tmp/triaxPackCache.sqlite',material=concreteId)
O.bodies.append(spheres)
bb=utils.uniaxialTestFeatures()
negIds,posIds,axis,crossSectionArea=bb['negIds'],bb['posIds'],bb['axis'],bb['area']
=== modified file 'gui/qt3/GLViewer.cpp'
--- gui/qt3/GLViewer.cpp 2009-12-04 23:46:45 +0000
+++ gui/qt3/GLViewer.cpp 2009-12-15 09:41:07 +0000
@@ -331,8 +331,8 @@
void GLViewer::centerPeriodic(){
Scene* rb=Omega::instance().getScene().get();
assert(rb->isPeriodic);
- Vector3r center=.5*(rb->cellMin+rb->cellMax);
- Vector3r halfSize=.5*(rb->cellMax-rb->cellMin);
+ Vector3r center=.5*rb->cellSize;
+ Vector3r halfSize=.5*rb->cellSize;
float radius=std::max(halfSize[0],std::max(halfSize[1],halfSize[2]));
LOG_DEBUG("Periodic scene center="<<center<<", halfSize="<<halfSize<<", radius="<<radius);
setSceneCenter(qglviewer::Vec(center[0],center[1],center[2]));
=== modified file 'pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp'
--- pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2009-12-11 07:27:29 +0000
+++ pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2009-12-15 09:41:07 +0000
@@ -37,7 +37,7 @@
geomDispatcher->updateScenePtr();
physDispatcher->updateScenePtr();
lawDispatcher->updateScenePtr();
- Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cellMax-scene->cellMin;
+ Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cellSize;
bool removeUnseenIntrs=(scene->interactions->iterColliderLastRun>=0 && scene->interactions->iterColliderLastRun==scene->currentIteration);
#ifdef YADE_OPENMP
const long size=scene->interactions->size();
=== modified file 'pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp'
--- pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp 2009-12-09 16:43:25 +0000
+++ pkg/common/Engine/Dispatcher/InteractionGeometryDispatcher.cpp 2009-12-15 09:41:07 +0000
@@ -48,7 +48,7 @@
updateScenePtr();
shared_ptr<BodyContainer>& bodies = scene->bodies;
- Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cellMax-scene->cellMin;
+ Vector3r cellSize; if(scene->isPeriodic) cellSize=scene->cellSize;
bool removeUnseenIntrs=(scene->interactions->iterColliderLastRun>=0 && scene->interactions->iterColliderLastRun==scene->currentIteration);
#ifdef YADE_OPENMP
const long size=scene->interactions->size();
=== modified file 'pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp'
--- pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp 2009-12-09 17:11:51 +0000
+++ pkg/common/Engine/GlobalEngine/InsertionSortCollider.cpp 2009-12-15 09:41:07 +0000
@@ -214,7 +214,7 @@
BBj[i].coord=((BBj[i].flags.hasBB=((bool)bv)) ? (BBj[i].flags.isMin ? bv->min[j] : bv->max[j]) : (b->state->pos[j])) - (periodic ? BBj.cellDim*BBj[i].period : 0.);
} else { BBj[i].flags.hasBB=false; /* for vanished body, keep the coordinate as-is, to minimize inversions. */ }
// if initializing periodic, shift coords & record the period into BBj[i].period
- if(doInitSort && periodic) BBj[i].coord=cellWrap(BBj[i].coord,BBj.cellMin,BBj.cellMax,BBj[i].period);
+ if(doInitSort && periodic) BBj[i].coord=cellWrap(BBj[i].coord,0,BBj.cellDim,BBj[i].period);
}
}
// for each body, copy its minima and maxima, for quick checks of overlaps later
@@ -296,7 +296,7 @@
return x0+(xNorm-period)*(x1-x0);
}
-// return coordinate wrapped to x0â¦x1, relative to x0; don't care about period
+// return coordinate wrapped to 0â¦x1, relative to x0; don't care about period
Real InsertionSortCollider::cellWrapRel(const Real x, const Real x0, const Real x1){
Real xNorm=(x-x0)/(x1-x0);
return (xNorm-floor(xNorm))*(x1-x0);
@@ -309,7 +309,7 @@
const long i=v.norm(_i);
const long i_1=v.norm(i-1);
//switch period of (i) if the coord is below the lower edge cooridnate-wise and just above the split
- if(i==loIdx && v[i].coord<v.cellMin){ v[i].period-=1; v[i].coord+=v.cellDim; loIdx=v.norm(loIdx+1); }
+ if(i==loIdx && v[i].coord<0){ v[i].period-=1; v[i].coord+=v.cellDim; loIdx=v.norm(loIdx+1); }
// coordinate of v[i] used to check inversions
// if crossing the split, adjust by cellDim;
// if we get below the loIdx however, the v[i].coord will have been adjusted already, no need to do that here
@@ -323,7 +323,7 @@
long j1=v.norm(j+1);
// OK, now if many bodies move at the same pace through the cell and at one point, there is inversion,
// this can happen without any side-effects
- if (false && v[j].coord>v.cellMax+v.cellDim){
+ if (false && v[j].coord>2*v.cellDim){
// this condition is not strictly necessary, but the loop of insertionSort would have to run more times.
// Since size of particle is required to be < .5*cellDim, this would mean simulation explosion anyway
LOG_FATAL("Body #"<<v[j].id<<" going faster than 1 cell in one step? Not handled.");
@@ -332,7 +332,7 @@
Bounds& vNew(v[j1]); // elt at j+1 being overwritten by the one at j and adjusted
vNew=v[j];
// inversions close the the split need special care
- if(j==loIdx && vi.coord<v.cellMin) { vi.period-=1; vi.coord+=v.cellDim; loIdx=v.norm(loIdx+1); }
+ if(j==loIdx && vi.coord<0) { vi.period-=1; vi.coord+=v.cellDim; loIdx=v.norm(loIdx+1); }
else if(j1==loIdx) { vNew.period+=1; vNew.coord-=v.cellDim; loIdx=v.norm(loIdx-1); }
if(doCollide && viHasBB && v[j].flags.hasBB){
if(vi.id==vNew.id){ // BUG!!
@@ -399,7 +399,7 @@
assert(periodic);
assert(id1!=id2); // programming error, or weird bodies (too large?)
for(int axis=0; axis<3; axis++){
- Real dim=rb->cellMax[axis]-rb->cellMin[axis];
+ Real dim=rb->cellSize[axis];
// too big bodies in interaction
assert(maxima[3*id1+axis]-minima[3*id1+axis]<.99*dim); assert(maxima[3*id2+axis]-minima[3*id2+axis]<.99*dim);
// find body of which when taken as period start will make the gap smaller
=== modified file 'pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp'
--- pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp 2009-12-09 17:11:51 +0000
+++ pkg/common/Engine/GlobalEngine/InsertionSortCollider.hpp 2009-12-15 09:41:07 +0000
@@ -53,7 +53,7 @@
Periodicity control
===================
c++:
- Scene::isPeriodic, Scene::cellMin, Scene::cellMax
+ Scene::isPeriodic, Scene::cellSize
python:
O.periodicCell=((0,0,0),(10,10,10) # activates periodic boundary
O.periodicCell=() # deactivates periodic boundary
@@ -148,7 +148,7 @@
// axis set in the ctor
int axis;
std::vector<Bounds> vec;
- Real cellMin, cellMax, cellDim;
+ Real cellDim;
// cache vector size(), update at every step in action()
long size;
// index of the lowest coordinate element, before which the container wraps
@@ -159,7 +159,7 @@
void updatePeriodicity(Scene* rb){
assert(rb->isPeriodic);
assert(axis>=0 && axis <=2);
- cellMin=rb->cellMin[axis]; cellMax=rb->cellMax[axis]; cellDim=cellMax-cellMin;
+ cellDim=rb->cellSize[axis];
}
// normalize given index to the right range (wraps around)
long norm(long i) const { if(i<0) i+=size; long ret=i%size; assert(ret>=0 && ret<size); return ret;}
=== modified file 'pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp'
--- pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp 2009-12-14 18:49:06 +0000
+++ pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp 2009-12-15 09:41:07 +0000
@@ -111,13 +111,13 @@
/* mostly copied from PeriodicInsertionSortCollider
FIXME: common implementation somewhere */
-Real OpenGLRenderingEngine::wrapCell(const Real x, const Real x0, const Real x1){
- Real xNorm=(x-x0)/(x1-x0);
- return x0+(xNorm-floor(xNorm))*(x1-x0);
+Real OpenGLRenderingEngine::wrapCell(const Real x, const Real x1){
+ Real xNorm=(x)/(x1);
+ return (xNorm-floor(xNorm))*(x1);
}
Vector3r OpenGLRenderingEngine::wrapCellPt(const Vector3r& pt, Scene* rb){
if(!rb->isPeriodic) return pt;
- return Vector3r(wrapCell(pt[0],rb->cellMin[0],rb->cellMax[0]),wrapCell(pt[1],rb->cellMin[1],rb->cellMax[1]),wrapCell(pt[2],rb->cellMin[2],rb->cellMax[2]));
+ return Vector3r(wrapCell(pt[0],rb->cellSize[0]),wrapCell(pt[1],rb->cellSize[1]),wrapCell(pt[2],rb->cellSize[2]));
}
void OpenGLRenderingEngine::setBodiesDispInfo(const shared_ptr<Scene>& rootBody){
@@ -148,8 +148,8 @@
if(!rootBody->isPeriodic) return;
glPushMatrix();
glColor3v(Vector3r(1,1,0));
- Vector3r cent=.5*(rootBody->cellMin+rootBody->cellMax); Vector3r size=rootBody->cellMax-rootBody->cellMin;
- glTranslate(cent[0],cent[1],cent[2]); glScale(size[0],size[1],size[2]);
+ Vector3r cent=.5*rootBody->cellSize;
+ glTranslate(cent[0],cent[1],cent[2]); glScale(rootBody->cellSize[0],rootBody->cellSize[1],rootBody->cellSize[2]);
glutWireCube(1);
glPopMatrix();
}
@@ -373,7 +373,7 @@
// if the body goes over the cell margin, draw it in positions where the bbox overlaps with the cell in wire
// precondition: pos is inside the cell.
if(b->bound && rootBody->isPeriodic){
- const Vector3r& cellMin(rootBody->cellMin); const Vector3r& cellMax(rootBody->cellMax); Vector3r cellSize=cellMax-cellMin;
+ const Vector3r& cellSize(rootBody->cellSize);
// traverse all periodic cells around the body, to see if any of them touches
Vector3r halfSize=b->bound->max-b->bound->min; halfSize*=.5;
Vector3r pmin,pmax;
@@ -382,9 +382,9 @@
if(i[0]==0 && i[1]==0 && i[2]==0) continue; // middle; already rendered above
Vector3r pt=pos+Vector3r(cellSize[0]*i[0],cellSize[1]*i[1],cellSize[2]*i[2]);
pmin=pt-halfSize; pmax=pt+halfSize;
- if(pmin[0]<=cellMax[0] && pmax[0]>=cellMin[0] &&
- pmin[1]<=cellMax[1] && pmax[1]>=cellMin[1] &&
- pmin[2]<=cellMax[2] && pmax[2]>=cellMin[2]) {
+ if(pmin[0]<=cellSize[0] && pmax[0]>=0 &&
+ pmin[1]<=cellSize[1] && pmax[1]>=0 &&
+ pmin[2]<=cellSize[2] && pmax[2]>=0) {
glPushMatrix();
glTranslatev(pt);
glRotatef(angle*Mathr::RAD_TO_DEG,axis[0],axis[1],axis[2]);
=== modified file 'pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp'
--- pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp 2009-12-11 18:10:19 +0000
+++ pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp 2009-12-15 09:41:07 +0000
@@ -39,8 +39,8 @@
Real normSaw(Real t, Real period){ Real xi=(t-period*((int)(t/period)))/period; /* normalized value, (0-1⪠*/ return (xi<.5?2*xi:2-2*xi); }
Real normSquare(Real t, Real period){ Real xi=(t-period*((int)(t/period)))/period; /* normalized value, (0-1⪠*/ return (xi<.5?0:1); }
- //! wrap number to interval x0â¦x1
- Real wrapCell(const Real x, const Real x0, const Real x1);
+ //! wrap number to interval 0â¦x1
+ Real wrapCell(const Real x, const Real x1);
//! wrap point to inside Scene's cell (identity if !Scene::isPeriodic)
Vector3r wrapCellPt(const Vector3r& pt, Scene* rb);
void drawPeriodicCell(Scene*);
=== modified file 'pkg/dem/DataClass/SpherePack.cpp'
--- pkg/dem/DataClass/SpherePack.cpp 2009-12-13 20:30:13 +0000
+++ pkg/dem/DataClass/SpherePack.cpp 2009-12-15 09:41:07 +0000
@@ -75,7 +75,7 @@
if(!intSph) continue;
pack.push_back(Sph(b->state->pos,intSph->radius));
}
- if(rootBody->isPeriodic) { cellSize=rootBody->cellMax-rootBody->cellMin; }
+ if(rootBody->isPeriodic) { cellSize=rootBody->cellSize; }
}
long SpherePack::makeCloud(Vector3r mn, Vector3r mx, Real rMean, Real rRelFuzz, size_t num, bool periodic){
=== modified file 'pkg/dem/Engine/GlobalEngine/NewtonIntegrator.cpp'
--- pkg/dem/Engine/GlobalEngine/NewtonIntegrator.cpp 2009-12-09 17:11:51 +0000
+++ pkg/dem/Engine/GlobalEngine/NewtonIntegrator.cpp 2009-12-15 09:41:07 +0000
@@ -66,9 +66,8 @@
// account for motion of the periodic boundary, if we remember its last position
// its velocity will count as max velocity of bodies
// otherwise the collider might not run if only the cell were changing without any particle motion
- if(scene->isPeriodic && (prevCellMax!=scene->cellMax || prevCellMin!=scene->cellMin)){ cellChanged=true; maxVelocitySq=(prevCellMax-prevCellMin-(scene->cellMax-scene->cellMin)).SquaredLength()/pow(dt,2); }
+ if(scene->isPeriodic && (prevCellSize!=scene->cellSize)){ cellChanged=true; maxVelocitySq=(prevCellSize-scene->cellSize).SquaredLength()/pow(dt,2); }
else { maxVelocitySq=0; cellChanged=false; }
- prevCellSize=prevCellMax-prevCellMin; cellSize=scene->cellMax-scene->cellMin;
haveBins=(bool)velocityBins;
if(haveBins) velocityBins->binVelSqInitialize(maxVelocitySq);
@@ -152,7 +151,7 @@
FOREACH(const Real& thrMaxVSq, threadMaxVelocitySq) { maxVelocitySq=max(maxVelocitySq,thrMaxVSq); }
#endif
if(haveBins) velocityBins->binVelSqFinalize();
- if(scene->isPeriodic) { prevCellMax=scene->cellMax; prevCellMin=scene->cellMin; }
+ if(scene->isPeriodic) { prevCellSize=scene->cellSize; }
}
inline void NewtonIntegrator::leapfrogTranslate(Scene* scene, State* state, const body_id_t& id, const Real& dt )
@@ -162,8 +161,9 @@
// which is then used to compute new position x=ξ(xâ-xâ)+xâ. (per component)
// Then we update either velocity by (x-x')/Ît (homotheticCellResize==1)
// or position by (x-x') (homotheticCellResize==2)
- Vector3r dPos;
- if(cellChanged && homotheticCellResize){ for(int i=0; i<3; i++) dPos[i]=((state->pos[i]-prevCellMin[i])/(prevCellSize[i]))*cellSize[i]+scene->cellMin[i]-state->pos[i]; }
+ // FIXME: wrap state->pos first, then apply the shift; otherwise result might be garbage
+ Vector3r dPos(Vector3r::ZERO); // initialize to avoid warning; find way to avoid it in a better way
+ if(cellChanged && homotheticCellResize){ for(int i=0; i<3; i++) dPos[i]=(state->pos[i]/prevCellSize[i])*scene->cellSize[i]-state->pos[i]; }
blockTranslateDOFs(state->blockedDOFs, state->accel);
state->vel+=dt*state->accel; if(homotheticCellResize==1) state->vel+=dPos/dt;
state->pos += state->vel*dt + scene->bex.getMove(id); if(homotheticCellResize==2) state->pos+=dPos;
=== modified file 'pkg/dem/Engine/GlobalEngine/NewtonIntegrator.hpp'
--- pkg/dem/Engine/GlobalEngine/NewtonIntegrator.hpp 2009-12-09 17:11:51 +0000
+++ pkg/dem/Engine/GlobalEngine/NewtonIntegrator.hpp 2009-12-15 09:41:07 +0000
@@ -50,10 +50,8 @@
Quaternionr DotQ(const Vector3r& angVel, const Quaternionr& Q);
inline void blockTranslateDOFs(unsigned blockedDOFs, Vector3r& v);
inline void blockRotateDOFs(unsigned blockedDOFs, Vector3r& v);
- // cell corners from previous step, used to detect change, find max velocity and update positions if linearCellResize enabled
- Vector3r prevCellMax, prevCellMin;
- // cache sizes, recomputed before the loop at every step
- Vector3r prevCellSize, cellSize;
+ // cell size from previous step, used to detect change, find max velocity and update positions if linearCellResize enabled
+ Vector3r prevCellSize;
// whether the cell has changed from the previous step
bool cellChanged;
=== modified file 'pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp'
--- pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp 2009-12-06 17:18:16 +0000
+++ pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp 2009-12-15 09:41:07 +0000
@@ -33,7 +33,7 @@
}
if(maxDisplPerStep<0) maxDisplPerStep=1e-2*charLen; // this should be tuned somehowâ¦
const long& step=rb->currentIteration;
- Vector3r cellSize=rb->cellMax-rb->cellMin; //unused: Real cellVolume=cellSize[0]*cellSize[1]*cellSize[2];
+ Vector3r cellSize=rb->cellSize; //unused: Real cellVolume=cellSize[0]*cellSize[1]*cellSize[2];
Vector3r cellArea=Vector3r(cellSize[1]*cellSize[2],cellSize[0]*cellSize[2],cellSize[0]*cellSize[1]);
Real minSize=min(cellSize[0],min(cellSize[1],cellSize[2])), maxSize=max(cellSize[0],max(cellSize[1],cellSize[2]));
if(minSize<2.1*maxSpan){ throw runtime_error("Minimum cell size is smaller than 2.1*span_of_the_biggest_body! (periodic collider requirement)"); }
@@ -42,7 +42,7 @@
sigma=-Vector3r(sumForces[0]/cellArea[0],sumForces[1]/cellArea[1],sumForces[2]/cellArea[2]);
LOG_TRACE("Updated sigma="<<sigma<<", avgStiffness="<<avgStiffness);
}
- Real sigmaGoal=stresses[state]; assert(sigmaGoal>0);
+ Real sigmaGoal=stresses[state]; assert(sigmaGoal<0);
// expansion of cell in this step (absolute length)
Vector3r cellGrow(Vector3r::ZERO);
// is the stress condition satisfied in all directions?
@@ -72,7 +72,7 @@
}
}
TRVAR4(cellGrow,sigma,sigmaGoal,avgStiffness);
- rb->cellMin-=.5*cellGrow; rb->cellMax+=.5*cellGrow;
+ rb->cellSize+=cellGrow;
// handle state transitions
if(allStressesOK){
if((step%globalUpdateInt)==0) currUnbalanced=Shop::unbalancedForce(/*useMaxForce=*/false,rb);
@@ -91,7 +91,7 @@
void PeriTriaxController::strainStressStiffUpdate(){
// update strain first
- const Vector3r cellSize(scene->cellMax-scene->cellMin);
+ const Vector3r& cellSize(scene->cellSize);
for(int i=0; i<3; i++) strain[i]=(cellSize[i]-refSize[i])/refSize[i];
// stress and stiffness
Vector3r sumForce(Vector3r::ZERO), sumStiff(Vector3r::ZERO), sumLength(Vector3r::ZERO);
@@ -122,7 +122,7 @@
void PeriTriaxController::action(Scene* scene){
if(!scene->isPeriodic){ throw runtime_error("PeriTriaxController run on aperiodic simulation."); }
- Vector3r cellSize=scene->cellMax-scene->cellMin;
+ const Vector3r& cellSize=scene->cellSize;
Vector3r cellArea=Vector3r(cellSize[1]*cellSize[2],cellSize[0]*cellSize[2],cellSize[0]*cellSize[1]);
// initial updates
if(refSize[0]<0) refSize=cellSize;
@@ -182,7 +182,7 @@
if(stiff[axis]>0) stress[axis]+=(cellGrow[axis]/refSize[axis])*(stiff[axis]/cellArea[axis]); //-bogusPoisson*(cellGrow[ax1]/refSize[ax1])*(stiff[ax1]/cellArea[ax1])-bogusPoisson*(cellGrow[ax2]/refSize[ax2])*(stiff[ax2]/cellArea[ax2]);
}
// change cell size now
- scene->cellMax+=cellGrow;
+ scene->cellSize+=cellGrow;
strainRate=cellGrow/scene->dt;
if(allOk){
=== modified file 'py/pack.py'
--- py/pack.py 2009-12-09 17:11:51 +0000
+++ py/pack.py 2009-12-15 09:41:07 +0000
@@ -304,10 +304,10 @@
if wantPeri:
# x1,y1,z1 already computed above
sp=SpherePack()
- O.periodicCell=((0,0,0),(x1,y1,z1))
+ O.periodicCell=Vector3(x1,y1,z1)
#print cloudPorosity,beta,gamma,N100,x1,y1,z1,O.periodicCell
#print x1,y1,z1,radius,rRelFuzz
- num=sp.makeCloud(O.periodicCell[0],O.periodicCell[1],radius,rRelFuzz,spheresInCell,True)
+ num=sp.makeCloud(Vector3().ZERO,O.periodicCell,radius,rRelFuzz,spheresInCell,True)
O.engines=[BexResetter(),BoundDispatcher([InteractingSphere2AABB()]),InsertionSortCollider(nBins=5,sweepLength=.05*radius),InteractionDispatchers([ef2_Sphere_Sphere_Dem3DofGeom()],[SimpleElasticRelationships()],[Law2_Dem3Dof_Elastic_Elastic()]),PeriIsoCompressor(charLen=radius/5.,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='O.pause();',globalUpdateInt=5,keepProportions=True),NewtonIntegrator(damping=.6)]
O.materials.append(GranularMat(young=30e9,frictionAngle=.5,poisson=.3,density=1e3))
for s in sp: O.bodies.append(utils.sphere(s[0],s[1]))
@@ -373,8 +373,8 @@
from math import pi
O.switchScene(); O.resetThisScene()
sp=SpherePack()
- O.periodicCell=((0,0,0),Vector3(initSize))
- sp.makeCloud(O.periodicCell[0],O.periodicCell[1],radius,rRelFuzz,int(initSize[0]*initSize[1]*initSize[2]/((4/3.)*pi*radius**3)),True)
+ O.periodicCell=Vector3(initSize)
+ sp.makeCloud(Vector3().ZERO,O.periodicCell,radius,rRelFuzz,int(initSize[0]*initSize[1]*initSize[2]/((4/3.)*pi*radius**3)),True)
O.engines=[BexResetter(),BoundDispatcher([InteractingSphere2AABB()]),InsertionSortCollider(nBins=2,sweepLength=.05*radius),InteractionDispatchers([Ig2_Sphere_Sphere_Dem3DofGeom()],[SimpleElasticRelationships()],[Law2_Dem3Dof_Elastic_Elastic()]),PeriIsoCompressor(charLen=2*radius,stresses=[-100e9,-1e8],maxUnbalanced=1e-2,doneHook='O.pause();',globalUpdateInt=20,keepProportions=True),NewtonIntegrator(damping=.8)]
O.materials.append(GranularMat(young=30e9,frictionAngle=.1,poisson=.3,density=1e3))
for s in sp: O.bodies.append(utils.sphere(s[0],s[1]))
=== modified file 'py/yadeWrapper/yadeWrapper.cpp'
--- py/yadeWrapper/yadeWrapper.cpp 2009-12-13 22:51:22 +0000
+++ py/yadeWrapper/yadeWrapper.cpp 2009-12-15 09:41:07 +0000
@@ -521,15 +521,13 @@
oa << YadeSimulation;
}
#endif
- void periodicCell_set(python::tuple& t){
- if(python::len(t)==2){ OMEGA.getScene()->cellMin=python::extract<Vector3r>(t[0]); OMEGA.getScene()->cellMax=python::extract<Vector3r>(t[1]); OMEGA.getScene()->isPeriodic=true; }
- else if (python::len(t)==0) {OMEGA.getScene()->isPeriodic=false; }
- else throw invalid_argument("Must pass either 2 Vector3's to set periodic cell, or () to disable periodicity (got "+lexical_cast<string>(python::len(t))+" instead).");
+ void periodicCell_set(Vector3r& size){
+ if(size[0]>0 && size[1]>0 && size[2]>0) { OMEGA.getScene()->cellSize=size; OMEGA.getScene()->isPeriodic=true; }
+ else {OMEGA.getScene()->isPeriodic=false; }
}
- python::tuple periodicCell_get(){
- vector<Vector3r> ret;
- if(OMEGA.getScene()->isPeriodic){ return python::make_tuple(OMEGA.getScene()->cellMin,OMEGA.getScene()->cellMax); }
- return python::make_tuple();
+ Vector3r periodicCell_get(){
+ if(OMEGA.getScene()->isPeriodic) return OMEGA.getScene()->cellSize;
+ return Vector3r(-1,-1,-1);
}
void disableGdb(){
signal(SIGSEGV,SIG_DFL);
=== modified file 'scripts/test/pack-cloud.py'
--- scripts/test/pack-cloud.py 2009-12-04 23:27:26 +0000
+++ scripts/test/pack-cloud.py 2009-12-15 09:41:07 +0000
@@ -1,8 +1,8 @@
""" Generate random periodic sphere packing using SpherePack::makeCloud """
from yade import pack
p=pack.SpherePack()
-O.periodicCell=(0,0,0),(10,10,10)
-print p.makeCloud(O.periodicCell[0],O.periodicCell[1],.5,.5,1200,True)
+O.periodicCell=Vector3(10,10,10)
+print p.makeCloud(Vector3().ZERO,O.periodicCell[1],.5,.5,1200,True)
for s in p:
O.bodies.append(utils.sphere(s[0],s[1]))
O.runEngine(BoundDispatcher([InteractingSphere2AABB()]))
=== modified file 'scripts/test/periodic-compress.py'
--- scripts/test/periodic-compress.py 2009-12-11 18:10:19 +0000
+++ scripts/test/periodic-compress.py 2009-12-15 09:41:07 +0000
@@ -1,7 +1,7 @@
-O.periodicCell=(0,0,0),(20,20,10)
+O.periodicCell=Vector3(20,20,10)
from yade import pack,log,timing
p=pack.SpherePack()
-p.makeCloud(O.periodicCell[0],O.periodicCell[1],1,.5,700,True)
+p.makeCloud(Vector3().ZERO,O.periodicCell,1,.5,700,True)
for sph in p:
O.bodies.append(utils.sphere(sph[0],sph[1]))
=== modified file 'scripts/test/periodic-grow.py'
--- scripts/test/periodic-grow.py 2009-12-11 18:10:19 +0000
+++ scripts/test/periodic-grow.py 2009-12-15 09:41:07 +0000
@@ -19,7 +19,7 @@
O.bodies.append(utils.sphere(Vector3(10*random.random(),10*random.random(),10*random.random()),.5+random.random()))
cubeSize=20
# absolute positioning of the cell is not important
-O.periodicCell=((-.5*cubeSize,-.5*cubeSize,0),(.5*cubeSize,.5*cubeSize,cubeSize))
+O.periodicCell=Vector3(cubeSize,cubeSize,cubeSize)
O.dt=utils.PWaveTimeStep()
O.saveTmp()
from yade import qt
@@ -28,12 +28,10 @@
O.run(200,True)
for i in range(0,250):
O.run(200,True)
- mn,mx=O.periodicCell
- step=(mx-mn); step=Vector3(.002*step[0],.002*step[1],.002*step[2])
- O.periodicCell=mn+step,mx-step
+ O.periodicCell=O.periodicCell*.998
if (i%10==0):
F,stiff=utils.totalForceInVolume()
- dim=mx-mn; A=Vector3(dim[1]*dim[2],dim[0]*dim[2],dim[0]*dim[1])
+ dim=O.periodicCell; A=Vector3(dim[1]*dim[2],dim[0]*dim[2],dim[0]*dim[1])
avgStress=sum([F[i]/A[i] for i in 0,1,2])/3.
print 'strain',(cubeSize-dim[0])/cubeSize,'avg. stress ',avgStress,'unbalanced ',utils.unbalancedForce()
#O.timingEnabled=True; timing.reset(); O.run(200000,True); timing.stats()
=== modified file 'scripts/test/periodic-simple.py'
--- scripts/test/periodic-simple.py 2009-12-11 18:10:19 +0000
+++ scripts/test/periodic-simple.py 2009-12-15 09:41:07 +0000
@@ -24,7 +24,7 @@
O.bodies.append(utils.sphere([0,2,5.5],2))
O.bodies.appendClumped([utils.sphere([0,4,8],.8),utils.sphere([0,5,7],.6)])
# sets up the periodic cell
-O.periodicCell=((-5,-5,0),(5,5,10))
+O.periodicCell=Vector3(10,10,10)
O.dt=.1*utils.PWaveTimeStep()
O.saveTmp()
from yade import qt
=== modified file 'scripts/test/periodic-triax.py'
--- scripts/test/periodic-triax.py 2009-12-09 17:11:51 +0000
+++ scripts/test/periodic-triax.py 2009-12-15 09:41:07 +0000
@@ -4,10 +4,10 @@
from yade import *
from yade import pack,log,qt
#log.setLevel('PeriTriaxController',log.DEBUG)
-O.periodicCell=(0,0,0),(.1,.1,.1)
+O.periodicCell=Vector3(.1,.1,.1)
sp=pack.SpherePack()
radius=5e-3
-num=sp.makeCloud(O.periodicCell[0],O.periodicCell[1],radius,.2,500,periodic=True) # min,max,radius,rRelFuzz,spheresInCell,periodic
+num=sp.makeCloud(Vector3().ZERO,O.periodicCell,radius,.2,500,periodic=True) # min,max,radius,rRelFuzz,spheresInCell,periodic
O.bodies.append([utils.sphere(s[0],s[1]) for s in sp])