← Back to team overview

yade-users team mailing list archive

Re: About SDEC packing


Hi Yuannian,

You can find an archive attached to this file. You can simply unzip it and replace your old "package-dem" by this one.
You will have a new file generator called TriaxialTest.
Generate a scene and run it, you will see spheres in between 6 rigid walls. The walls move until the stress applied reach one given value (that you can define when you generate the scene).

Note that this is already a method of packing!

The problem is that the initial positions are taken from a file.

So first step : "1/ Random generation in a box (without contact - without gravity) " needs something exactly similar to what Janek did for aggregates (this is the code I had written in Fish language). The corresponding part of his code is at the end of this message.
This way we won't need a pre-defined text file for positions.

When step 1 will be done. We will have a first random packing method. However, when the packing is compressed by moving walls (in place of increasing particle radii), it sometimes generate heterogeneous packings with big voids in the center (as you can observe in the TriaxialTest example).

The solution will be to consider step 2 : "Radii expansion until one prescibed value of the confining
   pressure is reached"

For this, we have to create a new engine that will modify the radii of particles, based on the confining pressure measured by an engine called "TriaxialStressController" (the one that moves walls). Or perhaps (simpler) add a function to TriaxialStressController that will modify radii. This is very simple in principle, but probably we will have to take care of different aspects (like updating the size of bounding boxes) when modifying radii of spheres.

step 3 :  "Possibly : decreasing slowly the contact friction to densify
   the packing" is in fact optionnal. We can speak of this latter.

Note : the time-step is computed here based on the global stiffness matrix of each grain. This is not in the current release of Yade.


struct Circle
	float x,y,r;

bool overlaps(Circle& cc,std::vector<Circle>& c)
	std::vector<Circle>::iterator end=c.end();
	for(std::vector<Circle>::iterator i=c.begin();i!=end;++i)
		float dist2 = std::pow(i->x - cc.x ,2)+std::pow(i->y - cc.y,2);
		float r2    = std::pow(i->r+cc.r ,2);
			return true;
	return false;

// random
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/normal_distribution.hpp>

void LatticeExample::addAggregates(shared_ptr<MetaBody>& rootBody)
	// first make a list of circles
	std::vector<Circle> c;
	float AGGREGATES_X=speciemen_size_in_meters[0];
	float AGGREGATES_Y=speciemen_size_in_meters[1];

	typedef boost::minstd_rand StdGenerator;
	static StdGenerator generator;
	static boost::variate_generator<StdGenerator&, boost::uniform_real<> >
		random1(generator, boost::uniform_real<>(0,1));
	static boost::variate_generator<StdGenerator&, boost::normal_distribution<> >
		randomN(generator, boost::normal_distribution<>(aggregateMeanRadius,aggregateSigmaRadius));

	std::cerr << "generating aggregates ... ";
		Circle cc;
		cc.x=random1()*AGGREGATES_X, cc.y=random1()*AGGREGATES_Y;
		for(int i=0 ; i<1000 ; ++i)
				cc.x=random1()*AGGREGATES_X, cc.y=random1()*AGGREGATES_Y;
		//		std::cerr << cc.x << " " << cc.y << " " << cc.r << "\n";
	while(aggregatePercent/100.0 > aggsAreas(c)/(AGGREGATES_X*AGGREGATES_Y) );
	std::cerr << "done. " << c.size() << " aggregates generated, area: " << aggsAreas(c)/(AGGREGATES_X*AGGREGATES_Y) << "\n";



Chareyre Bruno
     Maître de conférence
     Institut National Polytechnique de Grenoble

     Tél :

     Bureau I 08
     Laboratoire 3S (Soils Solids Structures)
     BP 53 - 38041, Grenoble cedex 9 - France

Attachment: package-dem-src.tar.gz
Description: application/gzip

Follow ups