yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #02913
[Branch ~yade-dev/yade/trunk] Rev 1937: 1. Add clone function to python objects, taking optinal python dictionary with changed attributes
------------------------------------------------------------
revno: 1937
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Mon 2010-01-04 11:34:53 +0100
message:
1. Add clone function to python objects, taking optinal python dictionary with changed attributes
2. Fix PeriIsoCompressor for examples/concrete/periodic.py
3. GaussAverage relThreshold argument is now optional in python, as it is in c++ (again)
modified:
examples/concrete/periodic.py
pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp
py/WeightedAverage2d.cpp
py/yadeWrapper/yadeWrapper.cpp
--
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.
=== modified file 'examples/concrete/periodic.py'
--- examples/concrete/periodic.py 2009-12-25 14:46:48 +0000
+++ examples/concrete/periodic.py 2010-01-04 10:34:53 +0000
@@ -70,7 +70,7 @@
# load the packing (again);
#
import cPickle as pickle
-concreteId=O.materials.append(CpmMat(young=young,frictionAngle=frictionAngle,poisson=poisson,density=4800))
+concreteId=O.materials.append(CpmMat(young=young,frictionAngle=frictionAngle,poisson=poisson,density=4800,sigmaT=sigmaT,relDuctility=relDuctility,epsCrackOnset=epsCrackOnset,G_over_E=G_over_E,isoPrestress=isoPrestress))
sphDict=pickle.load(open(packingFile))
from yade import pack
sp=pack.SpherePack()
@@ -80,7 +80,8 @@
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.cellSize=sp.cellSize
+O.periodic=True
+O.cell.refSize=sp.cellSize
axis=2
ax1=(axis+1)%3
ax2=(axis+2)%3
@@ -96,7 +97,7 @@
InsertionSortCollider(sweepLength=.05*avgRadius,nBins=5,binCoeff=5),
InteractionDispatchers(
[Ig2_Sphere_Sphere_Dem3DofGeom(distFactor=intRadius,label='ss2d3dg')],
- [Ip2_CpmMat_CpmMat_CpmPhys(sigmaT=sigmaT,relDuctility=relDuctility,epsCrackOnset=epsCrackOnset,G_over_E=G_over_E,isoPrestress=isoPrestress)],
+ [Ip2_CpmMat_CpmMat_CpmPhys()],
[Law2_Dem3DofGeom_CpmPhys_Cpm()],
),
NewtonIntegrator(damping=damping,label='newton'),
@@ -104,7 +105,7 @@
#
#UniaxialStrainer(strainRate=strainRateTension,axis=axis,asymmetry=0,posIds=posIds,negIds=negIds,crossSectionArea=crossSectionArea,blockDisplacements=False,blockRotations=False,setSpeeds=setSpeeds,label='strainer'),
#
- PeriTriaxController(goal=[1,1,1],stressMask=( (7^(1<<axis | 1<<ax1)) if biaxial else (7^(1<<axis)) ),maxStrainRate=Vector3(1,1,1),label='strainer',reversedForces=False,globUpdate=2),
+ PeriTriaxController(goal=[1,1,1],stressMask=( (7^(1<<axis | 1<<ax1)) if biaxial else (7^(1<<axis)) ),maxStrainRate=Vector3(5,5,5),label='strainer',reversedForces=False,globUpdate=2),
PeriodicPythonRunner(virtPeriod=1e-5/strainRateTension,realLim=2,command='addPlotData()',label='plotDataCollector'),
PeriodicPythonRunner(realPeriod=4,command='stopIfDamaged()',label='damageChecker'),
]
=== modified file 'pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp'
--- pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp 2010-01-03 20:30:24 +0000
+++ pkg/dem/Engine/GlobalEngine/PeriIsoCompressor.cpp 2010-01-04 10:34:53 +0000
@@ -101,7 +101,7 @@
//"Natural" strain, correct for large deformations, only used for comparison with goals
// â no logarithm here, I have code for strain-stress test that needs regular linear strain.
// Why not set goals as logarithm, if you need it?
- for ( int i=0; i<3; i++ ) strain[i]=(scene->cell->trsf[i][i]);
+ for(int i=0; i<3; i++) strain[i]=(scene->cell->getSize()[i]-scene->cell->refSize[i])/(scene->cell->refSize[i]);
//stress tensor and stiffness
@@ -233,14 +233,15 @@
// either prescribe velocity gradient
//NOTE (2) : ... and don't divide here
scene->cell->velGrad[axis][axis]=cellGrow[axis]/(scene->dt*refSize[axis]);
- // or strain increment (but NOT both)
- // strain[axis]+=cellGrow[axis]/refSize[axis];
+ // used only for goal comparisons...
+ strain[axis]+=cellGrow[axis]/refSize[axis];
// take in account something like poisson's effect hereâ¦
//Real bogusPoisson=0.25; int ax1=(axis+1)%3,ax2=(axis+2)%3;
//don't modify stress if dynCell, testing only stiff[axis]>0 would not allow switching the control mode in simulations,
///NOTE : this one uses size and is hard to generalize to 9 components as well, how can we predict the full stress tensor? It would need a 9x9 stifness matrix!! At the end, I wonder if the implementation of independant control on the 9 components would not be easier and cleaner in a different engine... This stiffness approach is not a piece of cake. Controlling arbitrary components using inertia and comparing Fkk vs. goal[k][k] is really a different (and easier) problem. I feel like I'm mixing two different things, with a lot of complication to preserve a few specific features that will not be generalised at the end, just for the sake of avoiding a few duplicated lines. What do you think?
- if ( stiff[axis]>0 && !dynCell ) 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]);
+ if (stiff[axis]>0 && !dynCell) 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->cell->refSize+=cellGrow;
=== modified file 'py/WeightedAverage2d.cpp'
--- py/WeightedAverage2d.cpp 2009-11-13 11:27:22 +0000
+++ py/WeightedAverage2d.cpp 2010-01-04 10:34:53 +0000
@@ -17,7 +17,7 @@
BOOST_PYTHON_MODULE(WeightedAverage2d)
{
boost::python::scope().attr("__doc__")="Smoothing (2d gauss-weighted average) for postprocessing scalars in 2d.";
- boost::python::class_<pyGaussAverage>("GaussAverage",python::init<python::tuple,python::tuple,python::tuple,Real,Real>(python::args("min","max","nCells","stDev","relThreshold"),"Create empty container for data, which can be added using add and later retrieved using avg."))
+ boost::python::class_<pyGaussAverage>("GaussAverage",python::init<python::tuple,python::tuple,python::tuple,Real,python::optional<Real> >(python::args("min","max","nCells","stDev","relThreshold"),"Create empty container for data, which can be added using add and later retrieved using avg."))
.def("add",&pyGaussAverage::addPt)
.def("avg",&pyGaussAverage::avg)
.add_property("stDev",&pyGaussAverage::stDev_get,&pyGaussAverage::stDev_set)
=== modified file 'py/yadeWrapper/yadeWrapper.cpp'
--- py/yadeWrapper/yadeWrapper.cpp 2010-01-03 20:30:24 +0000
+++ py/yadeWrapper/yadeWrapper.cpp 2010-01-04 10:34:53 +0000
@@ -575,6 +575,18 @@
return instance;
}
+template <typename T>
+shared_ptr<T> Serializable_clone(const shared_ptr<T>& self, const python::dict& d){
+ shared_ptr<Factorable> inst0=ClassFactory::instance().createShared(self->getClassName());
+ if(!inst0) throw runtime_error("Invalid class `"+self->getClassName()+"' (not created by ClassFactory).");
+ shared_ptr<T> inst=dynamic_pointer_cast<T>(inst0);
+ if(!inst) throw runtime_error("Invalid class `"+self->getClassName()+"' (unable to cast to typeid `"+typeid(T).name()+"')");
+ inst->pyUpdateAttrs(self->pyDict());
+ // if d not empty (how to test that?)
+ inst->pyUpdateAttrs(d);
+ inst->postProcessAttributes(/*deserializing*/true);
+ return inst;
+}
// stupid; Dispatcher is not a template, hence converting this into a real constructor would be complicated; keep it here.
template<typename DispatcherT>
@@ -751,6 +763,7 @@
.add_property("name",&Serializable::getClassName).def("__str__",&Serializable::pyStr).def("__repr__",&Serializable::pyStr).def("postProcessAttributes",&Serializable::postProcessAttributes,(python::arg("deserializing")=true))
.def("dict",&Serializable::pyDict).def("__getitem__",&Serializable::pyGetAttr).def("__setitem__",&Serializable::pySetAttr).def("has_key",&Serializable::pyHasKey).def("keys",&Serializable::pyKeys)
.def("updateAttrs",&Serializable::pyUpdateAttrs).def("updateExistingAttrs",&Serializable::pyUpdateExistingAttrs)
+ .def("clone",&Serializable_clone<Serializable>,python::arg("attrs")=python::dict())
.def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<Serializable>))
// aliases for __getitem__ and __setitem__, but they are used by the property generator code and can be useful if we deprecate the object['attr'] type of access
.def("_prop_get",&Serializable::pyGetAttr).def("_prop_set",&Serializable::pySetAttr)
@@ -800,7 +813,7 @@
EXPOSE_FUNCTOR(LawFunctor)
#undef EXPOSE_FUNCTOR
- #define EXPOSE_CXX_CLASS_RENAMED(cxxName,pyName) python::class_<cxxName,shared_ptr<cxxName>, python::bases<Serializable>, noncopyable>(#pyName).def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<cxxName>))
+ #define EXPOSE_CXX_CLASS_RENAMED(cxxName,pyName) python::class_<cxxName,shared_ptr<cxxName>, python::bases<Serializable>, noncopyable>(#pyName).def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<cxxName>)).def("clone",&Serializable_clone<cxxName>,python::arg("attrs")=python::dict())
#define EXPOSE_CXX_CLASS(className) EXPOSE_CXX_CLASS_RENAMED(className,className)
// expose indexable class, with access to the index
#define EXPOSE_CXX_CLASS_IX(className) EXPOSE_CXX_CLASS(className).add_property("dispIndex",&Indexable_getClassIndex<className>,"Return class index of this instance.").def("dispHierarchy",&Indexable_getClassIndices<className>,(python::arg("names")=true),"Return list of dispatch classes (from down upwards), starting with the class instance itself, top-level indexable at last. If names is true (default), return class names rather than numerical indices.")
Follow ups