yade-users team mailing list archive
-
yade-users team
-
Mailing list archive
-
Message #00320
Function for sphere packing
Hello all,
I think some of you (Yuannian, Lionel,...) will be interested by the
function "GenerateCloud" I have pasted at the end of this post, which
generate a cloud of non-overlapping spheres inside a box (thanks to the
number generator from Janek;)).
I use it in the triaxial test file generator, but I have not made it a
member of TriaxialTest, so that it is easy to re-use by simply copy-paste.
The number of generated sphere can be arbitrary high. However, if you
require a porosity that is too low (~less than 0.7), the number of
grains will be less than "number".
It can be used this way (this is a code from TriaxialTest::generate()):
shared_ptr<Body> body;
vector<BasicSphere> sphere_list;
string output = GenerateCloud(sphere_list, lowerCorner, upperCorner,
numberOfGrains, 0.3, 0.7);
vector<BasicSphere>::iterator it = sphere_list.begin();
vector<BasicSphere>::iterator it_end = sphere_list.end();
for (;it!=it_end; ++it)
{
cerr << "sphere (" << it->first << " " << it->second << endl;
createSphere(body,it->first,it->second,false,true);
rootBody->bodies->insert(body);
}
Using this fonction together with TriaxialStressController, it is now
possible to generate compact random assemblies in Yade :).
I am not completly satisfied by this method, so all this is still in
development....
BTW (Janek?...):
1) I want to increase the radii of spheres during the simulation, is it
enough to multiply the radius by "r" and the size of the bounding boxes
by the same "r"??
2) Is the group-mask stuff working currently?
Thanks
Bruno
// 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>
using namespace boost;
using namespace std;
typedef pair<Vector3r, Real> BasicSphere;
//! make a list of spheres non-overlapping sphere
string GenerateCloud(vector<BasicSphere>& sphere_list, Vector3r
lowerCorner, Vector3r upperCorner, long number, Real rad_std_dev, Real
porosity);
string GenerateCloud(vector<BasicSphere>& sphere_list, Vector3r
lowerCorner, Vector3r upperCorner, long number, Real rad_std_dev, Real
porosity)
{
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));
sphere_list.clear();
long tries = 1000; //nb of tries for positionning the next sphere
Vector3r dimensions = upperCorner - lowerCorner;
Real mean_radius =
std::pow(dimensions.x()*dimensions.y()*dimensions.z()*(1-porosity)/(3.1416*1.3333*number),0.333333);
//cerr << mean_radius;
std::cerr << "generating aggregates ... ";
long t, i;
for (i=0; i<number; ++i) {
BasicSphere s;
for (t=0; t<tries; ++t) {
s.second = (random1()-0.5)*rad_std_dev*mean_radius+mean_radius;
s.first.x() =
lowerCorner.x()+s.second+(dimensions.x()-2*s.second)*random1();
s.first.y() =
lowerCorner.y()+s.second+(dimensions.y()-2*s.second)*random1();
s.first.z() =
lowerCorner.z()+s.second+(dimensions.z()-2*s.second)*random1();
bool overlap=false;
for (long j=0; (j<i && !overlap); j++)
if ( pow(sphere_list[j].second+s.second, 2) >
(sphere_list[j].first-s.first).squaredLength()) overlap=true;
if (!overlap)
{
sphere_list.push_back(s);
break;
}
}
if (t==tries) return "More than " + lexical_cast<string>(tries) +
" tries while generating sphere number " +
lexical_cast<string>(i+1) + "/" +
lexical_cast<string>(number) + ".";
}
return "Generated a sample with " + lexical_cast<string>(number) +
"spheres inside box of dimensions: ("
+ lexical_cast<string>(dimensions[0]) + ","
+ lexical_cast<string>(dimensions[1]) + ","
+ lexical_cast<string>(dimensions[2]) + ").";
}
--
_______________
Chareyre Bruno
Maître de conférence
Institut National Polytechnique de Grenoble
Laboratoire 3S (Soils Solids Structures) - bureau I08
BP 53 - 38041, Grenoble cedex 9 - France
Tél : 04.56.52.86.21
________________
_______________________________________________
Yade-users mailing list
Yade-users@xxxxxxxxxxxxxxxx
http://bat.berlios.de/mailman/listinfo/yade-users
Follow ups