yade-users team mailing list archive
-
yade-users team
-
Mailing list archive
-
Message #00207
Re: About SDEC packing
Hi
It's a fun coincidence that currently I'm adding aggregates to my
lattice model. So that I will simulate concrete with aggregates.
I just want to send you now my filegenerator for lattice, the code that
generates aggregates is at the bottom of LatticeExample.cpp
I use geometry-based generation method. Pick random coordinates and
random radius and try to put it into the speciemen. Do this until
certian aggregates compacticy is obtaioned, very primitive method. It is 2D.
Just compile this filegenerator, run it, then load scene.xml. Make sure
that you set SimulationController->Display->drawWireFrame option. Now
you can see generated aggragates (nodes that belong to an aggregate have
black color)
look into the code (bottom of file). You will see that I use
boost::random library - I recommend using it:
// 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>
// this below creates a random number generator between 0 and 1 with
// uniform distribution
static boost::variate_generator<StdGenerator&, boost::uniform_real<> >
random1(generator, boost::uniform_real<>(0,1));
// this creates a random number generator with Gaussian distribution
// the parameter is mean, and sigma (parameters of gaussian distribution)
static boost::variate_generator<StdGenerator&, boost::normal_distribution<> >
randomN(generator, boost::normal_distribution<>(aggregateMeanRadius,aggregateSigmaRadius));
boost::random has more random distributions to choose from, look here:
http://www.boost.org/libs/random/index.html
http://www.boost.org/libs/random/random-distributions.html
I hope that this will help you with problem "I need to find a random number generator" :)
I you have any questions just ask.
--
Janek Kozicki |
/*************************************************************************
* Copyright (C) 2004 by Janek Kozicki *
* cosurgi@xxxxxxxxxx *
* *
* This program is free software; it is licensed under the terms of the *
* GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/
#include "LatticeExample.hpp"
#include "LatticeSetParameters.hpp"
#include "LatticeBeamParameters.hpp"
#include "LatticeBeamAngularSpring.hpp"
#include "NonLocalDependency.hpp"
#include "LatticeNodeParameters.hpp"
#include "LineSegment.hpp"
#include "LatticeLaw.hpp"
//#include "StrainRecorder.hpp"
//#include "NonLocalInitializer.hpp"
#include <yade/yade-package-common/Sphere.hpp>
#include <yade/yade-core/Body.hpp>
#include <yade/yade-package-common/MetaInteractingGeometry.hpp>
#include <yade/yade-package-common/BoundingVolumeMetaEngine.hpp>
#include <yade/yade-package-common/GeometricalModelMetaEngine.hpp>
#include <yade/yade-package-common/AABB.hpp>
#include <yade/yade-package-common/BodyRedirectionVector.hpp>
#include <yade/yade-package-common/InteractionVecSet.hpp>
#include <yade/yade-package-common/PhysicalActionVectorVector.hpp>
#include <yade/yade-package-common/DisplacementEngine.hpp>
#include <yade/yade-package-common/PhysicalParametersMetaEngine.hpp>
#include <yade/yade-package-common/PhysicalActionApplier.hpp>
#include <yade/yade-package-common/PhysicalActionContainerInitializer.hpp>
using namespace boost;
using namespace std;
LatticeExample::LatticeExample() : FileGenerator()
{
nodeGroupMask = 1;
beamGroupMask = 2;
speciemen_size_in_meters = Vector3r(0.1,0.1,0.0001);
cellsizeUnit_in_meters = 0.002;
minAngle_betweenBeams_deg= 20.0;
disorder_in_cellsizeUnit = Vector3r(0.6,0.6,0.0);
maxLength_in_cellsizeUnit= 1.9;
triangularBaseGrid = true;
useNonLocalModel = false;
useBendTensileSoftening = false;
useStiffnessSoftening = false;
nonLocalL_in_cellsizeUnit = 1.1; // l
crit_TensileStrain_percent = 100.0; // E_min
crit_ComprStrain_percent = 50.0; // E_max
longitudalStiffness_noUnit = 1.0; // k_l
bendingStiffness_noUnit = 0.0; // k_b
region_A_min = Vector3r(-0.006, 0.096,-1);
region_A_max = Vector3r( 0.16 , 0.16 , 1);
direction_A = Vector3r(0,1,0);
displacement_A_meters = 0.0001;
region_B_min = Vector3r(-0.006,-0.006,-1);
region_B_max = Vector3r( 0.16 , 0.004, 1);
direction_B = Vector3r(0,-1,0);
displacement_B_meters = 0.0001;
region_C_min = Vector3r(-0.006, 0.096,-1);
region_C_max = Vector3r( 0.16 , 0.16 , 1);
direction_C = Vector3r(0,1,0);
displacement_C_meters = 0.0001;
region_D_min = Vector3r(-0.006,-0.006,-1);
region_D_max = Vector3r( 0.16 , 0.004, 1);
direction_D = Vector3r(0,-1,0);
displacement_D_meters = 0.0001;
strainRecorder_xz_plane = -1;
outputFile = "../data/strains";
subscribedBodies.clear();
regionDelete_A_min = Vector3r(0,0,0);
regionDelete_A_max = Vector3r(0,0,0);
regionDelete_B_min = Vector3r(0,0,0);
regionDelete_B_max = Vector3r(0,0,0);
regionDelete_C_min = Vector3r(0,0,0);
regionDelete_C_max = Vector3r(0,0,0);
regionDelete_D_min = Vector3r(0,0,0);
regionDelete_D_max = Vector3r(0,0,0);
regionDelete_E_min = Vector3r(0,0,0);
regionDelete_E_max = Vector3r(0,0,0);
regionDelete_F_min = Vector3r(0,0,0);
regionDelete_F_max = Vector3r(0,0,0);
nonDestroy_A_min = Vector3r(0,0,0);
nonDestroy_A_max = Vector3r(0,0,0);
nonDestroy_B_min = Vector3r(0,0,0);
nonDestroy_B_max = Vector3r(0,0,0);
useAggregates = true;
aggregatePercent = 60;
aggregateMeanRadius = cellsizeUnit_in_meters*3;
aggregateSigmaRadius = cellsizeUnit_in_meters;
agg_longStiffness_noUnit= longitudalStiffness_noUnit*10; // k_l
agg_bendStiffness_noUnit= bendingStiffness_noUnit*10; // k_b
}
LatticeExample::~LatticeExample()
{
}
void LatticeExample::registerAttributes()
{
REGISTER_ATTRIBUTE(speciemen_size_in_meters); // size
REGISTER_ATTRIBUTE(cellsizeUnit_in_meters); // g [m] - cell size
REGISTER_ATTRIBUTE(minAngle_betweenBeams_deg); // a [deg] - min angle
REGISTER_ATTRIBUTE(disorder_in_cellsizeUnit); // s [-] - disorder
REGISTER_ATTRIBUTE(maxLength_in_cellsizeUnit); // r [-] - max beam length
REGISTER_ATTRIBUTE(crit_TensileStrain_percent); // E_min [%] - default 0.02 %
REGISTER_ATTRIBUTE(crit_ComprStrain_percent); // E_max [%] - default 0.2 %
REGISTER_ATTRIBUTE(longitudalStiffness_noUnit); // k_l [-] - default 1.0
REGISTER_ATTRIBUTE(bendingStiffness_noUnit); // k_b [-] - default 0.6
REGISTER_ATTRIBUTE(triangularBaseGrid); // - triangles
REGISTER_ATTRIBUTE(useBendTensileSoftening);
REGISTER_ATTRIBUTE(useStiffnessSoftening);
REGISTER_ATTRIBUTE(useNonLocalModel);
REGISTER_ATTRIBUTE(nonLocalL_in_cellsizeUnit); // l
REGISTER_ATTRIBUTE(region_A_min);
REGISTER_ATTRIBUTE(region_A_max);
REGISTER_ATTRIBUTE(direction_A);
REGISTER_ATTRIBUTE(displacement_A_meters);
REGISTER_ATTRIBUTE(region_B_min);
REGISTER_ATTRIBUTE(region_B_max);
REGISTER_ATTRIBUTE(direction_B);
REGISTER_ATTRIBUTE(displacement_B_meters);
REGISTER_ATTRIBUTE(region_C_min);
REGISTER_ATTRIBUTE(region_C_max);
REGISTER_ATTRIBUTE(direction_C);
REGISTER_ATTRIBUTE(displacement_C_meters);
REGISTER_ATTRIBUTE(region_D_min);
REGISTER_ATTRIBUTE(region_D_max);
REGISTER_ATTRIBUTE(direction_D);
REGISTER_ATTRIBUTE(displacement_D_meters);
REGISTER_ATTRIBUTE(strainRecorder_xz_plane);
REGISTER_ATTRIBUTE(outputFile);
REGISTER_ATTRIBUTE(regionDelete_A_min);
REGISTER_ATTRIBUTE(regionDelete_A_max);
REGISTER_ATTRIBUTE(regionDelete_B_min);
REGISTER_ATTRIBUTE(regionDelete_B_max);
REGISTER_ATTRIBUTE(regionDelete_C_min);
REGISTER_ATTRIBUTE(regionDelete_C_max);
REGISTER_ATTRIBUTE(regionDelete_D_min);
REGISTER_ATTRIBUTE(regionDelete_D_max);
REGISTER_ATTRIBUTE(regionDelete_E_min);
REGISTER_ATTRIBUTE(regionDelete_E_max);
REGISTER_ATTRIBUTE(regionDelete_F_min);
REGISTER_ATTRIBUTE(regionDelete_F_max);
REGISTER_ATTRIBUTE(nonDestroy_A_min);
REGISTER_ATTRIBUTE(nonDestroy_A_max);
REGISTER_ATTRIBUTE(nonDestroy_B_min);
REGISTER_ATTRIBUTE(nonDestroy_B_max);
REGISTER_ATTRIBUTE(useAggregates);
REGISTER_ATTRIBUTE(aggregatePercent);
REGISTER_ATTRIBUTE(aggregateMeanRadius);
REGISTER_ATTRIBUTE(aggregateSigmaRadius);
REGISTER_ATTRIBUTE(agg_longStiffness_noUnit);
REGISTER_ATTRIBUTE(agg_bendStiffness_noUnit);
}
string LatticeExample::generate()
{
rootBody = shared_ptr<MetaBody>(new MetaBody);
createActors(rootBody);
positionRootBody(rootBody);
rootBody->persistentInteractions = shared_ptr<InteractionContainer>(new InteractionVecSet);
rootBody->volatileInteractions = shared_ptr<InteractionContainer>(new InteractionVecSet);
rootBody->actionParameters = shared_ptr<PhysicalActionContainer>(new PhysicalActionVectorVector);
rootBody->bodies = shared_ptr<BodyContainer>(new BodyRedirectionVector);
shared_ptr<Body> body;
Vector3r nbNodes = speciemen_size_in_meters / cellsizeUnit_in_meters;
if(triangularBaseGrid)
nbNodes[1] *= 1.15471; // bigger by sqrt(3)/2 factor
unsigned int totalNodesCount = 0;
for( int j=0 ; j<=nbNodes[1] ; j++ )
{
for( int i=0 ; i<=nbNodes[0] ; i++ )
for( int k=0 ; k<=nbNodes[2] ; k++)
{
shared_ptr<Body> node;
if(createNode(node,i,j,k))
rootBody->bodies->insert(node), ++totalNodesCount;
}
// strain recorder - set what to monitor
if( j == 0 && subscribedBodies.size() == 0 )
subscribedBodies.push_back(static_cast<unsigned int>(nbNodes[0]) / 2);
// if( j == static_cast<int>(nbNodes[0]) && subscribedBodies.size() == 1 )
// subscribedBodies.push_back(totalNodesCount- 4);// - static_cast<int>(nbNodes[0]) / 2);
// subscribedBodies.push_back( (static_cast<int>(nbNodes[0]))
// * (static_cast<int>(nbNodes[1]))
// * (static_cast<int>(nbNodes[2]))
// - static_cast<int>(nbNodes[0])/2);
}
subscribedBodies.push_back(totalNodesCount - static_cast<int>(nbNodes[0]) / 2);
BodyRedirectionVector bc;
bc.clear();
BodyContainer::iterator bi = rootBody->bodies->begin();
BodyContainer::iterator bi2;
BodyContainer::iterator biEnd = rootBody->bodies->end();
int beam_counter = 0;
float nodes_a=0;
float nodes_all = rootBody->bodies->size();
for( ; bi!=biEnd ; ++bi ) // loop over all nodes, to create beams
{
Body* bodyA = (*bi).get(); // first_node
bi2 = bi;
++bi2;
nodes_a+=1.0;
for( ; bi2!=biEnd ; ++bi2 )
{
Body* bodyB = (*bi2).get(); // all other nodes
// warning - I'm assuming that there are ONLY Nodes in the rootBody
LatticeNodeParameters* a = static_cast<LatticeNodeParameters*>(bodyA->physicalParameters.get());
LatticeNodeParameters* b = static_cast<LatticeNodeParameters*>(bodyB->physicalParameters.get());
if ((a->se3.position - b->se3.position).squaredLength() < std::pow(maxLength_in_cellsizeUnit*cellsizeUnit_in_meters,2) )
{
shared_ptr<Body> beam;
createBeam(beam,bodyA->getId(),bodyB->getId());
calcBeamPositionOrientationLength(beam);
if(checkMinimumAngle(bc,beam))
{
if( ++beam_counter % 100 == 0 )
cerr << "creating beam: " << beam_counter << " , " << ((nodes_a/nodes_all)*100.0) << " %\n";
bc.insert(beam);
}
}
}
}
bi = bc.begin();
biEnd = bc.end();
for( ; bi!=biEnd ; ++bi ) // loop over all newly created beams ...
{
shared_ptr<Body> b = *bi;
rootBody->bodies->insert(b); // .. to insert then into rootBody
// attach them to strain recorder
Real xz_plane = strainRecorder_xz_plane;
Real pos1 = (*(rootBody->bodies))[static_cast<LatticeBeamParameters*>( b->physicalParameters.get() )->id1]->physicalParameters->se3.position[1]; // beam first node
Real pos2 = (*(rootBody->bodies))[static_cast<LatticeBeamParameters*>( b->physicalParameters.get() )->id2]->physicalParameters->se3.position[1]; // beam second node
if( pos1 < pos2 )
std::swap(pos1,pos2); // make sure that pos1 is bigger
if( pos1 > xz_plane
&& pos2 < xz_plane
)
subscribedBodies.push_back( b->getId() ); // beam crosses the plane!
}
//strainRecorder->subscribedBodies = subscribedBodies;
//strainRecorder->initialLength = (*(rootBody->bodies))[subscribedBodies[0]]->physicalParameters->se3.position[1]
// - (*(rootBody->bodies))[subscribedBodies[1]]->physicalParameters->se3.position[1];
{ // remember what node is in contact with what beams
// node beams
connections.resize(totalNodesCount);
bi = rootBody->bodies->begin();
biEnd = rootBody->bodies->end();
for( ; bi!=biEnd ; ++bi ) // loop over all beams
{
Body* body = (*bi).get();
if( ! ( body->getGroupMask() & beamGroupMask ) )
continue; // skip non-beams
LatticeBeamParameters* beam = static_cast<LatticeBeamParameters*>(body->physicalParameters.get() );
connections[beam->id1].push_back(body->getId());
connections[beam->id2].push_back(body->getId());
}
}
{ // create angular springs between beams
bi = rootBody->bodies->begin();
biEnd = rootBody->bodies->end();
float all_bodies = rootBody->bodies->size();
int current = 0;
for( ; bi!=biEnd ; ++bi ) // loop over all beams
{
if( ++current % 100 == 0 )
cerr << "angular springs: " << current << " , " << ((static_cast<float>(current)/all_bodies)*100.0) << " %\n";
Body* body = (*bi).get();
if( ! ( body->getGroupMask() & beamGroupMask ) )
continue; // skip non-beams
calcBeamAngles(body,rootBody->bodies.get(),rootBody->persistentInteractions.get());
}
}
regionDelete(rootBody,regionDelete_A_min,regionDelete_A_max);
regionDelete(rootBody,regionDelete_B_min,regionDelete_B_max);
regionDelete(rootBody,regionDelete_C_min,regionDelete_C_max);
regionDelete(rootBody,regionDelete_D_min,regionDelete_D_max);
regionDelete(rootBody,regionDelete_E_min,regionDelete_E_max);
regionDelete(rootBody,regionDelete_F_min,regionDelete_F_max);
nonDestroy(rootBody,nonDestroy_A_min,nonDestroy_A_max);
nonDestroy(rootBody,nonDestroy_B_min,nonDestroy_B_max);
imposeTranslation(rootBody,region_A_min,region_A_max,direction_A,displacement_A_meters);
imposeTranslation(rootBody,region_B_min,region_B_max,direction_B,displacement_B_meters);
imposeTranslation(rootBody,region_C_min,region_C_max,direction_C,displacement_C_meters);
imposeTranslation(rootBody,region_D_min,region_D_max,direction_D,displacement_D_meters);
if(useAggregates) addAggregates(rootBody);
cerr << "finished.. saving\n";
return "Number of nodes created:\n" + lexical_cast<string>(nbNodes[0]) + ","
+ lexical_cast<string>(nbNodes[1]) + ","
+ lexical_cast<string>(nbNodes[2]);
}
/// returns true if angle is bigger than minAngle_betweenBeams_deg
bool LatticeExample::checkAngle( Vector3r a, Vector3r& b)
{
Quaternionr al;
al.align(a,b);
Vector3r axis;
Real angle;
al.toAxisAngle(axis, angle);
angle *= 180.0/Mathr::PI ;
// cerr << " angle: " << angle << "\n";
return angle > minAngle_betweenBeams_deg;
}
/// returns true if angle is bigger than minAngle_betweenBeams_deg
bool LatticeExample::checkMinimumAngle(BodyRedirectionVector& bc,shared_ptr<Body>& body)
{
bool answer = true;
LatticeBeamParameters* newBeam = static_cast<LatticeBeamParameters*>(body->physicalParameters.get());
BodyContainer::iterator bi = bc.begin();
BodyContainer::iterator biEnd = bc.end();
for( ; bi!=biEnd ; ++bi ) // loop over all beams - they MUST be beams, for static_cast<>
{
LatticeBeamParameters* oldBeam = static_cast<LatticeBeamParameters*>((*bi)->physicalParameters.get());
if( (oldBeam->id1 == newBeam->id1)
|| (oldBeam->id2 == newBeam->id2))
answer = answer && checkAngle( oldBeam->direction , newBeam->direction );
if( (oldBeam->id2 == newBeam->id1)
|| (oldBeam->id1 == newBeam->id2))
answer = answer && checkAngle( - oldBeam->direction , newBeam->direction );
}
return answer;
}
bool LatticeExample::createNode(shared_ptr<Body>& body, int i, int j, int k)
{
body = shared_ptr<Body>(new Body(0,nodeGroupMask));
shared_ptr<LatticeNodeParameters> physics(new LatticeNodeParameters);
shared_ptr<Sphere> gSphere(new Sphere);
Quaternionr q;
q.fromAxisAngle( Vector3r(Mathr::unitRandom(),Mathr::unitRandom(),Mathr::unitRandom()) , Mathr::unitRandom()*Mathr::PI );
float triang_x = triangularBaseGrid ? (static_cast<float>(j%2))*0.5 : 0;
double triang_y = triangularBaseGrid ? 0.86602540378443864676 : 1; // sqrt(3)/2
Vector3r position = ( Vector3r(i+triang_x,j*triang_y,k)
+ Vector3r( Mathr::symmetricRandom()*disorder_in_cellsizeUnit[0]
, Mathr::symmetricRandom()*disorder_in_cellsizeUnit[1]
, Mathr::symmetricRandom()*disorder_in_cellsizeUnit[2]
) * 0.5 // *0.5 because symmetricRandom is (-1,1), and disorder is whole size where nodes can appear
)*cellsizeUnit_in_meters;
if( position[0] >= speciemen_size_in_meters[0]
|| position[1] >= speciemen_size_in_meters[1]
|| position[2] >= speciemen_size_in_meters[2] )
return false;
Real radius = cellsizeUnit_in_meters*0.05;
body->isDynamic = true;
physics->se3 = Se3r(position,q);
gSphere->radius = radius;
gSphere->diffuseColor = Vector3f(0.8,0.8,0.8);
gSphere->wire = false;
gSphere->visible = true;
gSphere->shadowCaster = false;
body->geometricalModel = gSphere;
body->physicalParameters = physics;
//////////////////////
// do tego przyk³adu ustawiam wspó³rzêdne - FIXME - przyda³oby siê ³adowanie wspó³rzêdnych wierzcho³ków sk±din±d
//static int zzzzz=0;
//switch(zzzzz%5)
//{
// case 0 : physics->se3.position=Vector3r(0.4,1.5,0); break;
// case 1 : physics->se3.position=Vector3r(0.8,0.6,0); break;
// case 2 : physics->se3.position=Vector3r(0,0,0); break;
// case 3 : physics->se3.position=Vector3r(1.6,0.5,0); break;
// case 4 : physics->se3.position=Vector3r(2.0,0,0); break;
//};
//zzzzz++;
//
//////////////////////
return true;
}
void LatticeExample::createBeam(shared_ptr<Body>& body, unsigned int i, unsigned int j)
{
body = shared_ptr<Body>(new Body(0,beamGroupMask));
shared_ptr<LatticeBeamParameters> physics(new LatticeBeamParameters);
shared_ptr<LineSegment> gBeam(new LineSegment);
Real length = 1.0; // unspecified for now, calcBeamsPositionOrientationLength will calculate it
body->isDynamic = true;
physics->id1 = i;
physics->id2 = j;
gBeam->length = length;
gBeam->diffuseColor = Vector3f(0.6,0.6,0.6);
gBeam->wire = false;
gBeam->visible = true;
gBeam->shadowCaster = false;
body->geometricalModel = gBeam;
body->physicalParameters = physics;
}
void LatticeExample::calcBeamPositionOrientationLength(shared_ptr<Body>& body)
{
LatticeBeamParameters* beam = static_cast<LatticeBeamParameters*>(body->physicalParameters.get());
shared_ptr<Body>& bodyA = (*(rootBody->bodies))[beam->id1];
shared_ptr<Body>& bodyB = (*(rootBody->bodies))[beam->id2];
Se3r& se3A = bodyA->physicalParameters->se3;
Se3r& se3B = bodyB->physicalParameters->se3;
Se3r se3Beam;
se3Beam.position = (se3A.position + se3B.position)*0.5;
Vector3r dist = se3A.position - se3B.position;
Real length = dist.normalize();
beam->direction = dist;
beam->initialDirection = dist;
beam->length = length;
beam->initialLength = length;
beam->criticalTensileStrain = crit_TensileStrain_percent/100.0;
beam->criticalCompressiveStrain = crit_ComprStrain_percent/100.0;
beam->longitudalStiffness = longitudalStiffness_noUnit;
beam->bendingStiffness = bendingStiffness_noUnit;
se3Beam.orientation.align( Vector3r::UNIT_X , dist );
beam->se3 = se3Beam;
beam->se3Displacement.position = Vector3r(0.0,0.0,0.0);
beam->se3Displacement.orientation.align(dist,dist);
}
void LatticeExample::calcAxisAngle(LatticeBeamParameters* beam, BodyContainer* bodies, unsigned int otherId, InteractionContainer* ints, unsigned int thisId)
{
if( ! ints->find(otherId,thisId) && otherId != thisId )
{
LatticeBeamParameters* otherBeam = static_cast<LatticeBeamParameters*>( ((*(bodies))[ otherId ])->physicalParameters.get() );
// Quaternionr rotation;
// Vector3r axis;
Real angle;
// rotation.align( beam->direction , otherBeam->direction );
// rotation.toAxisAngle (axis, angle);
// Vector3r result = axis*angle;
angle = (beam->direction.cross(otherBeam->direction)[2] > 0.0 ? 1.0 : -1.0) * Mathr::aCos( beam->direction.dot(otherBeam->direction) );
shared_ptr<Interaction> interaction(new Interaction( thisId , otherId ));
shared_ptr<LatticeBeamAngularSpring> angularSpring(new LatticeBeamAngularSpring);
// angularSpring->initialAngle = result;
// angularSpring->angle = result;
// angularSpring->initialAngle = rotation;
// angularSpring->angle = rotation;
angularSpring->initialAngle = angle;
angularSpring->angle = angle;
interaction->isReal = true;
interaction->isNew = false;
interaction->interactionPhysics = angularSpring;
ints->insert(interaction);
}
}
void LatticeExample::calcBeamAngles(Body* body, BodyContainer* bodies, InteractionContainer* ints)
{
LatticeBeamParameters* beam = static_cast<LatticeBeamParameters*>(body->physicalParameters.get());
std::vector<unsigned int>::iterator i = connections[beam->id1].begin();
std::vector<unsigned int>::iterator end = connections[beam->id1].end();
for( ; i != end ; ++i )
calcAxisAngle(beam,bodies,*i,ints,body->getId());
i = connections[beam->id2].begin();
end = connections[beam->id2].end();
for( ; i != end ; ++i )
calcAxisAngle(beam,bodies,*i,ints,body->getId());
}
void LatticeExample::createActors(shared_ptr<MetaBody>& )
{
shared_ptr<BoundingVolumeMetaEngine> boundingVolumeDispatcher = shared_ptr<BoundingVolumeMetaEngine>(new BoundingVolumeMetaEngine);
boundingVolumeDispatcher->add("MetaInteractingGeometry","AABB","MetaInteractingGeometry2AABB");
shared_ptr<GeometricalModelMetaEngine> geometricalModelDispatcher = shared_ptr<GeometricalModelMetaEngine>(new GeometricalModelMetaEngine);
geometricalModelDispatcher->add("LatticeSetParameters","LatticeSetGeometry","LatticeSet2LatticeBeams");
// strainRecorder = shared_ptr<StrainRecorder>(new StrainRecorder);
// strainRecorder->outputFile = outputFile;
// strainRecorder->interval = 10;
rootBody->engines.clear();
rootBody->engines.push_back(boundingVolumeDispatcher);
rootBody->engines.push_back(shared_ptr<LatticeLaw>(new LatticeLaw));
rootBody->engines.push_back(geometricalModelDispatcher);
// rootBody->engines.push_back(strainRecorder);
rootBody->initializers.clear();
rootBody->initializers.push_back(boundingVolumeDispatcher);
rootBody->initializers.push_back(geometricalModelDispatcher);
if(useNonLocalModel)
{
// shared_ptr<NonLocalInitializer> nonLocalInitializer(new NonLocalInitializer);
// nonLocalInitializer->range = nonLocalL_in_cellsizeUnit * cellsizeUnit_in_meters;
// rootBody->initializers.push_back(nonLocalInitializer);
}
}
void LatticeExample::positionRootBody(shared_ptr<MetaBody>& rootBody)
{
rootBody->isDynamic = false;
Quaternionr q;
q.fromAxisAngle( Vector3r(0,0,1),0);
shared_ptr<LatticeSetParameters> physics(new LatticeSetParameters);
physics->se3 = Se3r(Vector3r(0,0,0),q);
physics->beamGroupMask = beamGroupMask;
physics->nodeGroupMask = nodeGroupMask;
//physics->useBendTensileSoftening= useBendTensileSoftening;
//physics->useStiffnessSoftening = useStiffnessSoftening;
shared_ptr<MetaInteractingGeometry> set(new MetaInteractingGeometry());
set->diffuseColor = Vector3f(0,0,1);
shared_ptr<AABB> aabb(new AABB);
aabb->diffuseColor = Vector3r(0,0,1);
shared_ptr<GeometricalModel> gm = dynamic_pointer_cast<GeometricalModel>(ClassFactory::instance().createShared("LatticeSetGeometry"));
gm->diffuseColor = Vector3f(1,1,1);
gm->wire = false;
gm->visible = true;
gm->shadowCaster = true;
rootBody->interactionGeometry = dynamic_pointer_cast<InteractingGeometry>(set);
rootBody->boundingVolume = dynamic_pointer_cast<BoundingVolume>(aabb);
rootBody->geometricalModel = gm;
rootBody->physicalParameters = physics;
}
void LatticeExample::imposeTranslation(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max, Vector3r direction, Real displacement)
{
shared_ptr<DisplacementEngine> translationCondition = shared_ptr<DisplacementEngine>(new DisplacementEngine);
translationCondition->displacement = displacement;
direction.normalize();
translationCondition->translationAxis = direction;
rootBody->engines.push_back((rootBody->engines)[rootBody->engines.size()-1]);
(rootBody->engines)[rootBody->engines.size()-2]=(rootBody->engines)[rootBody->engines.size()-3];
(rootBody->engines)[rootBody->engines.size()-3]=(rootBody->engines)[rootBody->engines.size()-4];
(rootBody->engines)[rootBody->engines.size()-4]=translationCondition;
translationCondition->subscribedBodies.clear();
BodyContainer::iterator bi = rootBody->bodies->begin();
BodyContainer::iterator biEnd = rootBody->bodies->end();
for( ; bi!=biEnd ; ++bi )
{
shared_ptr<Body> b = *bi;
if( b->getGroupMask() & nodeGroupMask )
{
Vector3r pos = b->physicalParameters->se3.position;
if( pos[0] > min[0]
&& pos[1] > min[1]
&& pos[2] > min[2]
&& pos[0] < max[0]
&& pos[1] < max[1]
&& pos[2] < max[2]
&& (b->getGroupMask() & nodeGroupMask)
)
{
b->isDynamic = false;
b->geometricalModel->diffuseColor = Vector3f(0.3,0.3,0.3);
translationCondition->subscribedBodies.push_back(b->getId());
}
}
}
}
void LatticeExample::regionDelete(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max)
{
vector<unsigned int> futureDeletes;
BodyContainer::iterator bi = rootBody->bodies->begin();
BodyContainer::iterator biEnd = rootBody->bodies->end();
for( ; bi!=biEnd ; ++bi )
{
shared_ptr<Body> b = *bi;
if( b->getGroupMask() & beamGroupMask )
{
Vector3r pos = b->physicalParameters->se3.position;
if( pos[0] > min[0]
&& pos[1] > min[1]
&& pos[2] > min[2]
&& pos[0] < max[0]
&& pos[1] < max[1]
&& pos[2] < max[2]
)
futureDeletes.push_back( b->getId() );
}
}
vector<unsigned int>::iterator vend = futureDeletes.end();
for( vector<unsigned int>::iterator vsta = futureDeletes.begin() ; vsta != vend ; ++vsta)
rootBody->bodies->erase(*vsta);
}
void LatticeExample::nonDestroy(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max)
{
vector<unsigned int> marked;
BodyContainer::iterator bi = rootBody->bodies->begin();
BodyContainer::iterator biEnd = rootBody->bodies->end();
for( ; bi!=biEnd ; ++bi )
{
shared_ptr<Body> b = *bi;
if( b->getGroupMask() & beamGroupMask )
{
Vector3r pos = b->physicalParameters->se3.position;
if( pos[0] > min[0]
&& pos[1] > min[1]
&& pos[2] > min[2]
&& pos[0] < max[0]
&& pos[1] < max[1]
&& pos[2] < max[2]
)
marked.push_back( b->getId() );
}
}
vector<unsigned int>::iterator vend = marked.end();
for( vector<unsigned int>::iterator vsta = marked.begin() ; vsta != vend ; ++vsta)
{
LatticeBeamParameters* beam = static_cast<LatticeBeamParameters*>( ((*(rootBody->bodies))[*vsta])->physicalParameters.get());
beam->criticalTensileStrain = 0.9;
beam->criticalCompressiveStrain = 0.9;
(*(rootBody->bodies))[beam->id1]->geometricalModel->diffuseColor = Vector3f(0.2,0.5,0.7);
(*(rootBody->bodies))[beam->id2]->geometricalModel->diffuseColor = Vector3f(0.2,0.5,0.7);
}
}
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);
if(dist2<r2)
return true;
}
return false;
};
bool aggInside(Vector3r& a,Vector3r& b,std::vector<Circle>& c)
{ // checks if nodes 'a','b' are inside any of aggregates from list '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 - a[0],2)+std::pow(i->y - a[1],2);
float r2 = std::pow(i->r,2);
if(dist2<r2)
{
dist2 = std::pow(i->x - b[0],2)+std::pow(i->y - b[1],2);
if(dist2<r2)
return true;
}
}
return false;
}
float aggsAreas(std::vector<Circle>& c)
{
float aggArea=0.0;
std::vector<Circle>::iterator end=c.end();
for(std::vector<Circle>::iterator i=c.begin();i!=end;++i)
aggArea += 3.14159265358979323846*std::pow(i->r ,2);
return aggArea;
}
// 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 ... ";
do
{
Circle cc;
cc.x=random1()*AGGREGATES_X, cc.y=random1()*AGGREGATES_Y;
cc.r=std::abs(randomN());
for(int i=0 ; i<1000 ; ++i)
if(overlaps(cc,c))
cc.x=random1()*AGGREGATES_X, cc.y=random1()*AGGREGATES_Y;
else
{
c.push_back(cc);
// std::cerr << cc.x << " " << cc.y << " " << cc.r << "\n";
break;
}
}
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";
{ // set different properties for beams that lie in an aggregate
BodyContainer::iterator bi = rootBody->bodies->begin();
BodyContainer::iterator biEnd = rootBody->bodies->end();
float all_bodies = rootBody->bodies->size();
int current = 0;
for( ; bi!=biEnd ; ++bi ) // loop over all beams
{
// if( ++current % 100 == 0 )
// cerr << "aggregate beams: " << current << " , " << ((static_cast<float>(current)/all_bodies)*100.0) << " %\n";
Body* body = (*bi).get();
if( ! ( body->getGroupMask() & beamGroupMask ) )
continue; // skip non-beams
LatticeBeamParameters* beam = static_cast<LatticeBeamParameters*>(body->physicalParameters.get());
if(aggInside( (*(rootBody->bodies))[beam->id1]->physicalParameters->se3.position
,(*(rootBody->bodies))[beam->id2]->physicalParameters->se3.position
,c ))
{
beam->longitudalStiffness = agg_longStiffness_noUnit;
beam->bendingStiffness = agg_bendStiffness_noUnit;
(*(rootBody->bodies))[beam->id1]->geometricalModel->diffuseColor = Vector3f(0.0,0.0,0.0);
(*(rootBody->bodies))[beam->id2]->geometricalModel->diffuseColor = Vector3f(0.0,0.0,0.0);
}
}
}
}
/*************************************************************************
* Copyright (C) 2004 by Janek Kozicki *
* cosurgi@xxxxxxxxxx *
* *
* This program is free software; it is licensed under the terms of the *
* GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/
#ifndef LATTICE_BOX_HPP
#define LATTICE_BOX_HPP
#include <yade/yade-core/FileGenerator.hpp>
#include <yade/yade-lib-wm3-math/Vector3.hpp>
#include <yade/yade-package-common/BodyRedirectionVector.hpp>
class LatticeBeamParameters;
class StrainRecorder;
class LatticeExample : public FileGenerator
{
private :
int nodeGroupMask,beamGroupMask;
// mesh generation
Vector3r speciemen_size_in_meters // size
,disorder_in_cellsizeUnit; // s
Real maxLength_in_cellsizeUnit // r
,minAngle_betweenBeams_deg // a
,cellsizeUnit_in_meters // g
,crit_TensileStrain_percent // E_min
,crit_ComprStrain_percent // E_max
,longitudalStiffness_noUnit // k_l
,bendingStiffness_noUnit // k_b
,nonLocalL_in_cellsizeUnit; // l
bool triangularBaseGrid
,useNonLocalModel
,useBendTensileSoftening
,useStiffnessSoftening;
// aggregates
bool useAggregates;
Real aggregatePercent
,aggregateMeanRadius
,aggregateSigmaRadius
,agg_longStiffness_noUnit // k_l
,agg_bendStiffness_noUnit; // k_b
void addAggregates(shared_ptr<MetaBody>& rootBody);
// conditions
Vector3r region_A_min
,region_A_max
,direction_A
,region_B_min
,region_B_max
,direction_B
,region_C_min
,region_C_max
,direction_C
,region_D_min
,region_D_max
,direction_D;
Real displacement_A_meters
,displacement_B_meters
,displacement_C_meters
,displacement_D_meters;
// strain recorder
std::vector< unsigned int > subscribedBodies;
Real strainRecorder_xz_plane;
shared_ptr<StrainRecorder> strainRecorder;
std::string outputFile;
// delete beams regions
Vector3r regionDelete_A_min
,regionDelete_A_max
,regionDelete_B_min
,regionDelete_B_max
,regionDelete_C_min
,regionDelete_C_max
,regionDelete_D_min
,regionDelete_D_max
,regionDelete_E_min
,regionDelete_E_max
,regionDelete_F_min
,regionDelete_F_max;
// non destroy areas
Vector3r nonDestroy_A_min
,nonDestroy_A_max
,nonDestroy_B_min
,nonDestroy_B_max;
std::vector< std::vector< unsigned int > > connections; // which node is in touch with what beams.
public :
LatticeExample();
virtual ~LatticeExample();
string generate();
void createActors(shared_ptr<MetaBody>& rootBody);
void positionRootBody(shared_ptr<MetaBody>& rootBody);
bool createNode(shared_ptr<Body>& body, int i, int j, int k);
void createBeam(shared_ptr<Body>& body, unsigned int i, unsigned int j);
void calcBeamPositionOrientationLength(shared_ptr<Body>& body);
void calcBeamAngles(Body* body, BodyContainer* bodies,InteractionContainer* ints);
void calcAxisAngle(LatticeBeamParameters* beam, BodyContainer* bodies, unsigned int otherId,InteractionContainer* ints,unsigned int thisId);
bool checkMinimumAngle(BodyRedirectionVector&,shared_ptr<Body>&);
bool checkAngle( Vector3r , Vector3r& );
void imposeTranslation(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max, Vector3r direction, Real velocity);
void regionDelete(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max);
void nonDestroy(shared_ptr<MetaBody>& rootBody, Vector3r min, Vector3r max);
virtual void registerAttributes();
REGISTER_CLASS_NAME(LatticeExample);
REGISTER_BASE_CLASS_NAME(FileGenerator);
};
REGISTER_SERIALIZABLE(LatticeExample,false);
#endif // LATTICE_BOX_HPP
Follow ups
References